diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/LICENSE.TXT b/deployed/joomgallery/administrator/components/com_joomgallery/LICENSE.TXT new file mode 100644 index 00000000..674d65a3 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/LICENSE.TXT @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/access.xml b/deployed/joomgallery/administrator/components/com_joomgallery/access.xml new file mode 100644 index 00000000..c866ddd2 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/access.xml @@ -0,0 +1,31 @@ + + +
+ + + + + + + + + + +
+
+ + + + + + + + +
+
+ + + + +
+
\ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/changelog.xml b/deployed/joomgallery/administrator/components/com_joomgallery/changelog.xml new file mode 100644 index 00000000..8908abe6 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/changelog.xml @@ -0,0 +1,401 @@ + + + + + Adding a modal header and footer to image selection field popup + Adding a modal header and footer to thumbnail selection field popup + + + Fix FTP upload option 'Delete from FTP' not checked by default + + + Fix problems in backend views + + + Fix misaligned toolbar buttons in the backend views + + + Fix PHP Notice / Warning + + + Fix SQL Injection Attack Vulnerability via image sorting options + + + Fix double scheme in BBcode + + + Fix removing an image from the favourites + + + + + Fix edit button not working correctly in extended configuration manager + + + Fix setting of permissions in the backend category and image view + + + Allow spaces in uploaded image file names + Fix deprecation warnings in PHP7 + + + + + Fix pagination glitches in the back end image manager + Remove unused and invalid credits + Add missing translation for back end AJAX upload form + + + Restore correct collapsing behavior in images tab of MiniJoom + + + Fix double translation of some language strings + Add prefix for MiniJoom when selecting category thumbnails to prevent conflicts with other MiniJoom instances + + + Restrict valid Itemids based on language + + + GitHub logo was not showing and project pages should open in new tabs + + + Clean up and sort strings in language files + + + + + Fix broken thumbnail selection for categories with MiniJoom + + + + + Pass selected image type to the selectimage method in the MiniJoom + + + Fix sending messages via phpmailer + + + Fix setting of permissions in the backend category and image view + + + Fix form field joomuser popup + + + Fix E_STRICT errors in category view + + + Featured images + + + Proportional watermark + Backend batch edit metadata + + + Use different language constant for default ordering entry + + + Optimize tables + + + Fix links to managers (approval) in JoomGallery control panel + + + Owner filter in the back end categories view + + + Setting about allowing users to change access level of categories was not applied + Icomoon Icons were missing in the MiniJoom + + + New, changed and moved configuration options + + + Refactor back end categories view (search tools) + Fix pagination glitches in back end images view + + + Refactor back end categories view (search tools) + + + Refactor back end images view (search tools) + Use listbox for owner selection up to specified user count + + + Fix concealed buttons in the reject popup of the back end images view + + + Fix wrong entries for images in maintenance orphans table + + + Fix filtering in user panel view + Fix filtering in user categories view + + + Clean up member vars in JoomConfig and TableJoomgalleryConfig + Use Bootstrap styled button in report view + Remove unused option jg_showdetailfavourite + + + Removal of Cooliris integration + + + New responsive motion gallery with touch gesture support + + + Quick editing of image data in the userpanel view + + + Limit the number of images in the motion bar + + + Use of https for retrieving Google Maps, if necessary + + + + + Fix filename validation in drag'n'drop upload + + + Exchange Mootools tooltips with Bootstrap tooltips + Fix close button not always displaying in DHTML box + + + Fix E_STRICT errors in gallery view + + + Remove unnecessary class 'tip' from button's class attribute + Fix some not working tooltips in the backend + + + Added missing language constant + + + Delete additional old files and folders during update + + + Prevent saving password in the browser + + + Remove 'nowrap' from CSS class 'jg_catorderlist' + Wrong ID of select boxes when configuring specific categories in JoomPlu + Also check details tables during migration check + + + Create a form field for Fineuploader in order to reduce code redundancy + Use Bootstrap button and modal in Thumbnail form field + + + Tooltips should be enabled with default styling for new installations + + + Use Bootstrap button and modal in image form field + Use Bootstrap button and modal in Joomuser form field + Small improvements for migration purposes + + + Changed context name for batch processing + + + Pagination disappeared on phones -> move to Joomla language strings + + + + + MiniJoom popup could not be used for multiple purposes on the same page + + + Use Bootstrap styled buttons in detail view + + + Corrected language file download links + + + Fatal error when trying to install invalid package + + + Delete the corresponding votes if an image is deleted + + + Clean table #__modules_menu on component uninstall + + + Enable possibility for future direct one-click-update through GitHub + + + Improving performance of maintenance manager by adding an index + + + Fix /e modified deprecated errors + + + Added onJoomAfterUpload event to FTP upload + + + Several fixes in language files + + + + + Links to Transifex languages removed because they don't work anymore + + + Images and categories for which the actual files and folders cannot be deleted for any reason are now deleted in the database anyway + + + JavaScript errors if language strings contained inverted commas + + + Upgrade to FineUploader 4.4.0 + Preview in Drag'n'Drop upload + Allow to change file name and image title in Drag'n'Drop upload + Options 'Original filename' and 'Delete original images after upload' didn't work correctly within Drag'n'Drop upload of MiniJoom (JoomPlu) + Javascript errors when using Drag'n'Drop upload + Change Javascript load sequence in MiniJoom (JoomPlu) + Avoid 'ROOT' entry in category drop down list in the case that no category has been created yet + + + New JAVA-Applet 5.1.1 Build 1706 + + + Use of JHtml::_('behavior.tabstate') to remember active tab states + + + # Wrong calculation and display of the number of categories created by an owner in the user categories view + + + Javascript validation in the 'Editimages' back end view did not work anymore + + + Javascript errors in some backend views (Mootools/jQuery issue) + + + Configuration setting 'Show owner instead of author if no author exists?' now also used for detail view + Enlarge database field lengths for 'alias' and 'catpath' in table #__joomgallery_catg + + + Support long file names up to 255 characters, shorten file names that are longer + The file size limit has not been checked for frontend uploads + Select button in Drag'n'Drop upload view not fully functional + + + Deprecated class JRules replaced with class JAccessRules + Now using IcoMoon icon fonts in the backend toolbar titles + + + The AJAX category selection did not work for inserting images or categories in an article + + + + + Inserting categories with JoomBu/JoomPlu not possible in some cases because category select box did not show any categories + Call to undefined method JDate::toFormat() when storing categories or images + + + Interface configuration parameters 'hidebackend' and 'showcatlink' not always working correctly + + + Password protected categories stopped working with the release of Joomla! 3.2.0 + + + Motion gallery not moving in Google Chrome + + + Strict standards + Ordering form field 'Ordering' renamed to 'Joomordering' due to conflicts with Joomla! form field 'Ordering' + Fatal error in 'Openimage' form field + Fatal errors in frontend models 'edit' and 'editcategory' + + + Error with PHP 5.4 and 5.5 when FTP layer is enabled + + + + + MooRainbow assets removed + + + Use only bootstrap tooltips in backend + + + Missing import of 'joomla.filesystem.file' in maintenance manager + Problem with 'task' parameter when using it in a system plugin + + + Syntax error in database query when creating zip archives of favourites + + + Wrong variable used in JoomGallery router + SQL errors when synchronizing votes and nametags + Missing import of 'joomla.filesystem.file' when synchronizing favourites + + + + + Improved display of EXIF data for devices with low resolution + + + Support of unicode aliases added + + + Timespan for upload limit + + + Performance optimization for back end image deletion + + + Consider only published menu items for Itemid + + + Consider settings for image title and description in interface + + + Possibility to exclude images from toplists and the search + + + Password-protected categories + Possibility to explicitly reject images and to send message about rejection reason + + + Colorpickers now using jQuery minicolors.js instead of Mootools mooRainbow.js + JFormField 'color' removed + + + Possibility to view the 'Changelog' after extension update and in the 'Help and Information' view + + + Error 'JPath::clean: $path is not a string' in FTP Upload view fixed + + + Counting image downloads, display statistics and number of downloads in front and back end + Configuration option 'jg_wrongvaluecolor' removed + + + Option for selecting whether sent mails should use only the site e-mail address as sender + Recipients of mails sent by JoomGallery are included as BCC from now on + Wrong filters were applied to image and category descriptions + + + Number of images and categories were not displayed if only one page exists + + + Use of FineUploader in MiniJoom for improved user experience + Quick upload buttons in gallery, category and sub-category view + Image title and description was not always displayed as configured in popup boxes + + + Update Fineuploader JS/CSS (AJAX Upload) to version 3.4.1 (now GPLv3) + + + Resolving naming conflict between fields 'Hidden' and 'Unpublished' in the german language + JFormFields 'owner' and 'cbowner' deleted because they aren't used anymore + + + Error in detail view when option 'Use real paths' is enabled + + + Error while sending messages via e-mail + + + + + diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/config.xml b/deployed/joomgallery/administrator/components/com_joomgallery/config.xml new file mode 100644 index 00000000..1f99097f --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/config.xml @@ -0,0 +1,53 @@ + + +
+ +
+
+ + + + +
+
+ + + + + +
+
\ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/controller.php b/deployed/joomgallery/administrator/components/com_joomgallery/controller.php new file mode 100644 index 00000000..945f0a94 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/controller.php @@ -0,0 +1,87 @@ +_ambit = JoomAmbit::getInstance(); + $this->_config = JoomConfig::getInstance(); + + /*$this->_mainframe = JFactory::getApplication('site'); + $this->_user = JFactory::getUser();*/ + $this->_db = JFactory::getDBO(); + + // Uncomment following line to disable update check + // $this->_config->set('jg_checkupdate', 0); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/controllers/ajaxupload.php b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/ajaxupload.php new file mode 100644 index 00000000..8d1fd638 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/ajaxupload.php @@ -0,0 +1,58 @@ +_config->get('jg_disableunrequiredchecks') && !count(JoomHelper::getAuthorisedCategories('joom.upload'))) + { + $this->setRedirect(JRoute::_($this->_ambit->getRedirectUrl('categories'), false), JText::_('No categories found into which you are allowed to upload'), 'notice'); + + return; + } + + parent::display($cachable, $urlparams); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/controllers/ajaxupload.raw.php b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/ajaxupload.raw.php new file mode 100644 index 00000000..242411a7 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/ajaxupload.raw.php @@ -0,0 +1,70 @@ + false); + + require_once JPATH_COMPONENT.'/helpers/upload.php'; + + $uploader = new JoomUpload(); + + if($image = $uploader->upload(JRequest::getCmd('type', 'ajax'))) + { + $result['success'] = true; + if(is_object($image)) + { + $result['id'] = $image->id; + $result['imgtitle'] = $image->imgtitle; + $result['thumbnailUrl'] = $this->_ambit->getImg('thumb_url', $image); + } + } + else + { + if($error = $uploader->getError()) + { + $result['error'] = $error; + } + else + { + $result['error'] = JText::_('COM_JOOMGALLERY_UPLOAD_ERROR_FILE_NOT_UPLOADED');; + } + } + + if($debug_output = $uploader->getDebugOutput()) + { + $result['debug_output'] = $debug_output; + } + + $doc = JFactory::getDocument(); + $doc->setMimeEncoding('text/plain'); + + echo json_encode($result); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/controllers/batchupload.php b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/batchupload.php new file mode 100644 index 00000000..29b96df2 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/batchupload.php @@ -0,0 +1,94 @@ +_config->get('jg_disableunrequiredchecks') && !count(JoomHelper::getAuthorisedCategories('joom.upload'))) + { + $this->setRedirect(JRoute::_($this->_ambit->getRedirectUrl('categories'), false), JText::_('No categories found into which you are allowed to upload'), 'notice'); + + return; + } + + parent::display($cachable, $urlparams); + } + + /** + * Uploads the selected zip archiv + * + * @return void + * @since 1.5.5 + */ + public function upload() + { + require_once JPATH_COMPONENT.'/helpers/upload.php'; + $uploader = new JoomUpload(); + if($uploader->upload(JRequest::getCmd('type', 'batch'))) + { + $msg = JText::_('COM_JOOMGALLERY_UPLOAD_MSG_SUCCESSFULL'); + $url = $this->_ambit->getRedirectUrl(); + + // Set custom redirect if we are asked for that + if($redirect = JRequest::getVar('redirect', '', '', 'base64')) + { + $url_decoded = base64_decode($redirect); + if(JURI::isInternal($url)) + { + $url = $url_decoded; + } + } + + $this->setRedirect(JRoute::_($url, false), $msg); + } + else + { + if($error = $uploader->getError()) + { + $this->setRedirect($this->_ambit->getRedirectUrl(), $error, 'error'); + } + } + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/controllers/categories.json.php b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/categories.json.php new file mode 100644 index 00000000..a7dac3a8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/categories.json.php @@ -0,0 +1,74 @@ +getModel('categories'); + + $action = JRequest::getCmd('action'); + $filter = JRequest::getInt('filter'); + $search = JRequest::getString('searchstring'); + $limitstart = JRequest::getInt('more'); + $current = JRequest::getInt('current'); + + echo new JJsonResponse($model->getAllowedCategories($action, $filter, $search, $limitstart, $current)); + } + + /** + * Method to save the submitted ordering values for records via AJAX. + * + * @return void + * @since 3.0 + */ + public function saveOrder() + { + require_once JPATH_BASE.'/components/com_languages/helpers/jsonresponse.php'; + + JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + + // Get the arrays from the request + $pks = JRequest::getVar('cid', null, 'post', 'array'); + $order = JRequest::getVar('order', null, 'post', 'array'); + $originalOrder = explode(',', JRequest::getString('original_order_values')); + + // Make sure something has changed + if($order !== $originalOrder) + { + // Create and load the categories table object + $table = JTable::getInstance('joomgallerycategories', 'Table'); + + if($table->saveorder($pks, $order)) + { + echo new JJsonResponse(); + } + } + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/controllers/categories.php b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/categories.php new file mode 100644 index 00000000..d1f07628 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/categories.php @@ -0,0 +1,531 @@ +registerTask('new', 'edit'); + $this->registerTask('apply', 'save'); + $this->registerTask('save2new', 'save'); + $this->registerTask('save2copy', 'save'); + $this->registerTask('unpublish', 'publish'); + #$this->registerTask('reject', 'approve'); + $this->registerTask('accesspublic', 'access'); + $this->registerTask('accessregistered', 'access'); + $this->registerTask('accessspecial', 'access'); + $this->registerTask('orderup', 'order'); + $this->registerTask('orderdown', 'order'); + } + + /** + * Publishes or unpublishes one or more categories + * + * @access public + * @return void + * @since 1.5.5 + */ + function publish() + { + // Initialize variables + $cid = JRequest::getVar('cid', array(), 'post', 'array'); + $task = JRequest::getCmd('task'); + $publish = (int)($task == 'publish'); + + if(empty($cid)) + { + $this->setRedirect($this->_ambit->getRedirectUrl(), JText::_('COM_JOOMGALLERY_COMMON_MSG_NO_CATEGORIES_SELECTED')); + $this->redirect(); + } + + $unchanged_categories = 0; + foreach($cid as $key => $id) + { + // Prune categories for which we aren't allowed to change the state + if(!JFactory::getUser()->authorise('core.edit.state', _JOOM_OPTION.'.category.'.$id)) + { + unset($cid[$key]); + $unchanged_categories++; + } + } + + if($unchanged_categories) + { + JError::raiseNotice(403, JText::plural('COM_JOOMGALLERY_CATMAN_ERROR_EDITSTATE_NOT_PERMITTED', $unchanged_categories)); + } + + $model = $this->getModel('categories'); + if($count = $model->publish($cid, $publish)) + { + if($count != 1) + { + $msg = JText::sprintf($publish ? 'COM_JOOMGALLERY_CATMAN_MSG_CATEGORIES_PUBLISHED' : 'COM_JOOMGALLERY_CATMAN_MSG_CATEGORIES_UNPUBLISHED', $count); + } + else + { + $msg = JText::_($publish ? 'COM_JOOMGALLERY_CATMAN_MSG_CATEGORY_PUBLISHED' : 'COM_JOOMGALLERY_CATMAN_MSG_CATEGORY_UNPUBLISHED'); + } + $this->setRedirect($this->_ambit->getRedirectUrl(), $msg); + } + else + { + $msg = JText::_('COM_JOOMGALLERY_COMMON_MSG_ERROR_PUBLISHING_UNPUBLISHING'); + $this->setRedirect($this->_ambit->getRedirectUrl(), $msg, 'error'); + } + } + + /** + * Approves or rejects one or more comments + * + * @access public + * @return void + * @since 1.5.5 + */ + function approve() + { + // Initialize variables + $cid = JRequest::getVar('cid', array(), 'post', 'array'); + $task = JRequest::getCmd('task'); + $publish = ($task == 'approve'); + + if(empty($cid)) + { + $this->setRedirect($this->_ambit->getRedirectUrl(), JText::_('COM_JOOMGALLERY_COMMON_MSG_NO_CATEGORIES_SELECTED')); + $this->redirect(); + } + + $unchanged_categories = 0; + foreach($cid as $key => $id) + { + // Prune categories for which we aren't allowed to change the state + if(!JFactory::getUser()->authorise('core.edit.state', _JOOM_OPTION.'.category.'.$id)) + { + unset($cid[$key]); + $unchanged_categories++; + } + } + + if($unchanged_categories) + { + JError::raiseNotice(403, JText::plural('COM_JOOMGALLERY_CATMAN_ERROR_EDITSTATE_NOT_PERMITTED', $unchanged_categories)); + } + + $model = $this->getModel('categories'); + if($count = $model->publish($cid, $publish, 'approve')) + { + if($count != 1) + { + $msg = JText::sprintf($publish ? 'COM_JOOMGALLERY_CATMAN_MSG_CATEGORIES_APPROVED' : 'COM_JOOMGALLERY_CATMAN_MSG_CATEGORIES_REJECTED', $count); + } + else + { + $msg = JText::_($publish ? 'COM_JOOMGALLERY_CATMAN_MSG_CATEGORY_APPROVED' : 'COM_JOOMGALLERY_CATMAN_MSG_CATEGORY_REJECTED'); + } + $this->setRedirect($this->_ambit->getRedirectUrl(), $msg); + } + else + { + $msg = JText::_('COM_JOOMGALLERY_COMMON_MSG_ERROR_APPROVING_REJECTING'); + $this->setRedirect($this->_ambit->getRedirectUrl(), $msg, 'error'); + } + } + + /** + * Removes one or more categories + * + * @access public + * @return void + * @since 1.5.5 + */ + function remove() + { + $ids = JRequest::getVar('cid', array(), '', 'array'); + + $model = $this->getModel('categories'); + try + { + $count = $model->delete($ids); + + if($count == 1) + { + $msg = JText::_('COM_JOOMGALLERY_CATMAN_MSG_CATEGORY_DELETED'); + } + else + { + $msg = JText::sprintf('COM_JOOMGALLERY_CATMAN_MSG_CATEGORIES_DELETED', $count); + } + + // Some messages are enqueued by the model + $this->setRedirect($this->_ambit->getRedirectUrl(), $msg); + } + catch(RuntimeException $e) + { + $this->setRedirect($this->_ambit->getRedirectUrl(), $e->getMessage(), 'error'); + } + } + + /** + * Removes one or more categories even though there + * are still images or sub-categories in them. + * + * @access public + * @return void + * @since 1.5.5 + */ + function deletecompletely() + { + $mainframe = JFactory::getApplication('administrator'); + $categories = $mainframe->getUserState('joom.categories.delete.categories'); + $images = $mainframe->getUserState('joom.categories.delete.images'); + + if(!$categories || !is_array($categories) || !count($categories)) + { + $this->setRedirect($this->_ambit->getRedirectUrl(), JText::_('COM_JOOMGALLERY_COMMON_MSG_NO_CATEGORIES_SELECTED'), 'notice'); + + return; + } + + require_once JPATH_COMPONENT.'/helpers/refresher.php'; + + $refresher = new JoomRefresher(array('msg' => true)); + + $img_count = $mainframe->getUserState('joom.categories.delete.img_count'); + if(is_null($img_count)) + { + $img_count = 0; + } + $cat_count = $mainframe->getUserState('joom.categories.delete.cat_count'); + if(is_null($cat_count)) + { + $cat_count = 0; + } + + $error = false; + + if($images && is_array($images) && count($images)) + { + $model = $this->getModel('images'); + $row = $model->getTable('joomgalleryimages'); + foreach($images as $key => $image) + { + // Check whether image still exists. + // It may have been deleted before if categories were selected + // to delete as well as their sub-categories. + if($row->load($image)) + { + try + { + $model->delete(array($image)); + } + catch(RuntimeException $e) + { + JLog::add($e->getMessage(), JLog::ERROR, 'jerror'); + $error = true; + break; + } + + $img_count++; + } + + unset($images[$key]); + + if(!$refresher->check()) + { + $mainframe->setUserState('joom.categories.delete.images', $images); + $mainframe->setUserState('joom.categories.delete.img_count', $img_count); + $refresher->refresh(); + } + } + } + + $model = $this->getModel('categories'); + $row = $model->getTable('joomgallerycategories'); + + $categories = $model->getOrderedCategories($categories, 'lft', 'DESC'); + + if(!$error) + { + foreach($categories as $key => $category) + { + // Check whether category still exists. + // It may have been deleted before if categories were selected + // to delete as well as their sub-categories. + if($row->load($category)) + { + try + { + $model->delete(array($category)); + } + catch(RuntimeException $e) + { + JLog::add($e->getMessage(), JLog::ERROR, 'jerror'); + break; + } + + $cat_count++; + } + + unset($categories[$key]); + + if(!$refresher->check() && count($categories)) + { + $mainframe->setUserState('joom.categories.delete.images', $images); + $mainframe->setUserState('joom.categories.delete.categories', $categories); + $mainframe->setUserState('joom.categories.delete.img_count', $img_count); + $mainframe->setUserState('joom.categories.delete.cat_count', $cat_count); + $refresher->refresh(); + } + } + } + + if($img_count) + { + if($img_count == 1) + { + $msg = JText::_('COM_JOOMGALLERY_CATMAN_MSG_IMAGE_DELETED'); + } + else + { + $msg = JText::sprintf('COM_JOOMGALLERY_CATMAN_MSG_IMAGES_DELETED', $img_count); + } + $mainframe->enqueueMessage($msg); + } + + if($cat_count == 1) + { + $msg = JText::_('COM_JOOMGALLERY_CATMAN_MSG_CATEGORY_DELETED'); + } + else + { + $msg = JText::sprintf('COM_JOOMGALLERY_CATMAN_MSG_CATEGORIES_DELETED', $cat_count); + } + + // Reset all user states of this task + $mainframe->setUserState('joom.categories.delete', null); + + $this->setRedirect($this->_ambit->getRedirectUrl(), $msg); + } + + /** + * Displays the edit form of a category + * + * @access public + * @return void + * @since 1.5.5 + */ + function edit() + { + JRequest::setVar('view', 'category'); + JRequest::setVar('layout', 'form'); + JRequest::setVar('hidemainmenu', 1); + + parent::display(); + } + + /** + * Saves a category + * + * @access public + * @return void + * @since 1.5.5 + */ + function save() + { + $model = $this->getModel('category'); + + // Check whether a redirect is requested + $redirect = false; + if($url = JRequest::getVar('redirect', '', '', 'base64')); + { + $url = base64_decode($url); + if(JURI::isInternal($url)) + { + $redirect = $url; + } + } + + if(JRequest::getCmd('task') == 'save2copy') + { + // Reset the ID and then treat the request as for apply. + // This way a new category will be created and after that + // it will be displayed right away + JRequest::setVar('cid', 0); + JRequest::setVar('task', 'apply'); + } + + if($cid = $model->store()) + { + if(!$redirect) + { + if(JRequest::getCmd('task') == 'save2new') + { + // Reset the ID after storing so that we + // will be redirected to an empty form + $cid = 0; + JRequest::setVar('task', 'apply'); + } + $redirect = $this->_ambit->getRedirectUrl(null, $cid); + } + + $msg = JText::_('COM_JOOMGALLERY_CATMAN_MSG_CATEGORY_SAVED'); + $this->setRedirect($redirect, $msg); + } + else + { + if(!$redirect) + { + $redirect = $this->_ambit->getRedirectUrl(); + } + + $msg = $model->getError(); + $this->setRedirect($redirect, $msg, 'error'); + } + } + + /** + * Moves the order of a category + * + * @access public + * @return void + * @since 1.5.5 + */ + function order() + { + $cid = JRequest::getVar('cid', array(), 'post', 'array'); + + // Direction + $dir = 1; + $task = JRequest::getCmd('task'); + if($task == 'orderup') + { + $dir = -1; + } + + if(isset($cid[0])) + { + if(!JFactory::getUser()->authorise('core.edit.state', _JOOM_OPTION.'.category.'.$cid[0])) + { + $msg = JText::_('COM_JOOMGALLERY_CATMAN_ERROR_EDITSTATE_NOT_PERMITTED'); + $this->setRedirect($this->_ambit->getRedirectUrl(), $msg, 'notice'); + + return; + } + + $row = JTable::getInstance('joomgallerycategories', 'Table'); + $row->load((int)$cid[0]); + $row->move($dir); + } + + $this->setRedirect($this->_ambit->getRedirectUrl()); + } + + /** + * Saves the order of the categories + * + * @access public + * @return void + * @since 1.5.5 + */ + function saveOrder() + { + JRequest::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + + // Get the arrays from the request + $pks = JRequest::getVar('cid', null, 'post', 'array'); + $order = JRequest::getVar('order', null, 'post', 'array'); + $originalOrder = explode(',', JRequest::getString('original_order_values')); + + // Make sure something has changed + if($order !== $originalOrder) + { + // Create and load the categories table object + $table = JTable::getInstance('joomgallerycategories', 'Table'); + + if($table->saveorder($pks, $order)) + { + $msg = JText::_('COM_JOOMGALLERY_COMMON_MSG_NEW_ORDERING_SAVED'); + $this->setRedirect($this->_ambit->getRedirectUrl(), $msg); + } + else + { + $this->setRedirect($this->_ambit->getRedirectUrl(), $table->getError(), 'error'); + } + } + else + { + // Nothing to reorder + $this->setRedirect(JRoute::_($this->_ambit->getRedirectUrl(), false)); + } + } + + /** + * Method to run batch operations + * + * @return void + * @since 3.0 + */ + public function batch() + { + JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + + $vars = $this->input->post->get('batch', array(), 'array'); + $cid = $this->input->post->get('cid', array(), 'array'); + + $model = $this->getModel('category'); + + // Attempt to run the batch operation + if($model->batch($vars, $cid)) + { + $this->setMessage(JText::_('JLIB_APPLICATION_SUCCESS_BATCH')); + } + else + { + $this->setMessage(JText::sprintf('JLIB_APPLICATION_ERROR_BATCH_FAILED', $model->getError()), 'error'); + } + + $this->setRedirect(JRoute::_($this->_ambit->getRedirectUrl(), false)); + } + + /** + * Cancel editing or creating a category + * + * @access public + * @return void + * @since 1.5.5 + */ + function cancel() + { + $this->setRedirect($this->_ambit->getRedirectUrl()); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/controllers/changelog.php b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/changelog.php new file mode 100644 index 00000000..d2cbd903 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/changelog.php @@ -0,0 +1,38 @@ +registerTask('unpublish', 'publish'); + $this->registerTask('reject', 'approve'); + } + + /** + * Publishes or unpublishes one or more comments + * + * @return void + * @since 1.5.5 + */ + public function publish() + { + // Initialize variables + $cid = JRequest::getVar('cid', array(), 'post', 'array'); + $task = JRequest::getCmd('task'); + $publish = ($task == 'publish'); + + if(empty($cid)) + { + $this->setRedirect($this->_ambit->getRedirectUrl(), JText::_('COM_JOOMGALLERY_COMMAN_MSG_NO_COMMENTS_SELECTED')); + $this->redirect(); + } + + $model = $this->getModel('comments'); + if($count = $model->publish($cid, $publish)) + { + if($count != 1){ + $msg = JText::sprintf($publish ? 'COM_JOOMGALLERY_COMMAN_MSG_COMMENTS_PUBLISHED' : 'COM_JOOMGALLERY_COMMAN_MSG_COMMENTS_UNPUBLISHED', $count); + } else { + $msg = JText::_($publish ? 'COM_JOOMGALLERY_COMMAN_MSG_COMMENT_PUBLISHED' : 'COM_JOOMGALLERY_COMMAN_MSG_COMMENT_UNPUBLISHED'); + } + $this->setRedirect($this->_ambit->getRedirectUrl(), $msg); + } + else + { + $msg = JText::_('COM_JOOMGALLERY_COMMON_MSG_ERROR_PUBLISHING_UNPUBLISHING'); + $this->setRedirect($this->_ambit->getRedirectUrl(), $msg, 'error'); + } + } + + /** + * Approves or rejects one or more comments + * + * @return void + * @since 1.5.5 + */ + public function approve() + { + // Initialize variables + $cid = JRequest::getVar('cid', array(), 'post', 'array'); + $task = JRequest::getCmd('task'); + $publish = ($task == 'approve'); + + if(empty($cid)) + { + $this->setRedirect($this->_ambit->getRedirectUrl(), JText::_('COM_JOOMGALLERY_COMMAN_MSG_NO_COMMENTS_SELECTED')); + $this->redirect(); + } + + $model = $this->getModel('comments'); + if($count = $model->publish($cid, $publish, 'approve')) + { + if($count != 1){ + $msg = JText::sprintf($publish ? 'COM_JOOMGALLERY_COMMAN_MSG_COMMENTS_APPROVED' : 'COM_JOOMGALLERY_COMMAN_MSG_COMMENTS_REJECTED', $count); + } else { + $msg = JText::_($publish ? 'COM_JOOMGALLERY_COMMAN_MSG_COMMENT_APPROVED' : 'COM_JOOMGALLERY_COMMAN_MSG_COMMENT_REJECTED'); + } + $this->setRedirect($this->_ambit->getRedirectUrl(), $msg); + } + else + { + $msg = JText::_('COM_JOOMGALLERY_COMMON_MSG_ERROR_APPROVING_REJECTING'); + $this->setRedirect($this->_ambit->getRedirectUrl(), $msg, 'error'); + } + } + + /** + * Removes one or more comments + * + * @return void + * @since 1.5.5 + */ + public function remove() + { + $model = $this->getModel('comments'); + $count = $model->delete(); + if($count === false){ + $msg = JText::_('COM_JOOMGALLERY_COMMAN_MSG_ERROR_DELETING_COMMENT'); + } else { + if($count == 1){ + $msg = JText::_('COM_JOOMGALLERY_COMMAN_MSG_COMMENT_DELETED'); + } else { + $msg = JText::sprintf('COM_JOOMGALLERY_COMMAN_MSG_COMMENTS_DELETED', $count); + } + } + + $this->setRedirect($this->_ambit->getRedirectUrl(), $msg); + } + + /** + * Removes all comments in the gallery + * + * @return void + * @since 1.5.5 + */ + public function reset() + { + // Delete all comments + $query = $this->_db->getQuery(true) + ->delete() + ->from(_JOOM_TABLE_COMMENTS); + $this->_db->setQuery($query); + + if(!$this->_db->query()) + { + // Redirect to maintenance manager because this task is usually launched there + $this->setRedirect($this->_ambit->getRedirectUrl('maintenance&tab=comments'), $this->_db->getErrorMsg(), 'error'); + return; + } + + // Redirect to maintenance manager because this task is usually launched there + $this->setRedirect($this->_ambit->getRedirectUrl('maintenance&tab=comments'), JText::_('COM_JOOMGALLERY_MAIMAN_CM_MSG_ALL_COMMENTS_DELETED')); + } + + /** + * Synchronizes the comments with users registered and existing images. + * + * Comments of users that aren't registed any more will be marked as written by guests. + * + * @return void + * @since 1.5.5 + */ + public function synchronize() + { + // Synchronize users-comments-images + $query = $this->_db->getQuery(true) + ->delete('c USING '._JOOM_TABLE_COMMENTS.' AS c') + ->leftJoin(_JOOM_TABLE_IMAGES.' AS i ON c.cmtpic = i.id') + ->where('i.id IS NULL'); + $this->_db->setQuery($query); + + if(!$this->_db->query()) + { + // Redirect to maintenance manager because this task is usually launched there + $this->setRedirect($this->_ambit->getRedirectUrl('maintenance&tab=comments'), $this->_db->getErrorMsg(), 'error'); + + return; + } + + $this->_db->getQuery(true) + ->update(_JOOM_TABLE_COMMENTS.' AS c') + ->leftJoin('#__users AS u ON c.userid = u.id') + ->set('c.userid = 0') + ->where('u.id IS NULL'); + $this->_db->setQuery($query); + + if(!$this->_db->query()) + { + // Redirect to maintenance manager because this task is usually launched there + $this->setRedirect($this->_ambit->getRedirectUrl('maintenance&tab=comments'), $this->_db->getErrorMsg(), 'error'); + + return; + } + + // Redirect to maintenance manager because this task is usually launched there + $this->setRedirect($this->_ambit->getRedirectUrl('maintenance&tab=comments'), JText::_('COM_JOOMGALLERY_MAIMAN_CM_MSG_COMMENTS_SYNCHRONIZED')); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/controllers/config.php b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/config.php new file mode 100644 index 00000000..6025b408 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/config.php @@ -0,0 +1,271 @@ +authorise('core.admin', _JOOM_OPTION)) + { + $this->setRedirect(JRoute::_($this->_ambit->getRedirectUrl(''), false), 'You are not allowed to configure this component', 'notice'); + $this->redirect(); + } + + // Register tasks + $this->registerTask('new', 'edit'); + $this->registerTask('apply', 'save'); + $this->registerTask('orderup', 'order'); + $this->registerTask('orderdown', 'order'); + + // Set view + if($this->_config->isExtended()) + { + JRequest::setVar('view', 'configs'); + } + else + { + JRequest::setVar('view', 'config'); + } + } + + /** + * Displays the edit form of a config row + * + * @return void + * @since 2.0 + */ + public function edit() + { + $id = JRequest::getInt('id'); + $cid = JRequest::getVar('cid', array(), 'post', 'array'); + + if(!$id && count($cid) && $cid[0]) + { + JRequest::setVar('id', (int) $cid[0]); + } + + JRequest::setVar('view', 'config'); + JRequest::setVar('hidemainmenu', 1); + + parent::display(); + } + + /** + * Saves the configuration + * + * @return void + * @since 1.5.5 + */ + public function save() + { + $config = JoomConfig::getInstance('admin'); + + $id = false; + $existing_row = 0; + $group_id = 0; + if($config->isExtended()) + { + $id = JRequest::getInt('id'); + $existing_row = JRequest::getInt('based_on'); + + if(!$id) + { + $group_id = JRequest::getInt('group_id'); + } + } + else + { + $id = 1; + } + + $post = JRequest::get('post'); + + if(!$id = $config->save($post, $id, $existing_row, $group_id)) + { + $this->setRedirect($this->_ambit->getRedirectUrl(), JText::_('COM_JOOMGALLERY_CONFIG_MSG_SETTINGS_ERROR'), 'error'); + + return; + } + + $propagate_changes = JRequest::getBool('propagate_changes'); + + // The changes have to be propagated to the other config rows + // if the default row was changed or if propagation is requested + $success = true; + if(!$id || $id == 1 || $propagate_changes) + { + $success = $this->getModel('configs')->propagateChanges($post, $id, $propagate_changes); + } + + if($success) + { + $controller = ''; + if(!$config->isExtended()) + { + if(JRequest::getCmd('task') == 'apply') + { + $controller = 'config'; + } + } + else + { + $controller = null; + } + $this->setRedirect($this->_ambit->getRedirectUrl($controller, $id, 'id'), JText::_('COM_JOOMGALLERY_CONFIG_MSG_SETTINGS_SAVED')); + } + else + { + $this->setRedirect($this->_ambit->getRedirectUrl(), $this->getModel('configs')->getError(), 'error'); + } + } + + /** + * Removes one or more config rows + * + * @return void + * @since 2.0 + */ + public function remove() + { + $config = JoomConfig::getInstance('admin'); + $cid = JRequest::getVar('cid', array(), 'post', 'array'); + + if(!count($cid)) + { + $this->setRedirect($this->_ambit->getRedirectUrl(), JText::_('COM_JOOMGALLERY_CONFIGS_NO_ROWS_SELECTED'), 'notice'); + + return; + } + + $count = 0; + foreach($cid as $config_id) + { + if($config->delete($config_id)) + { + $count++; + } + else + { + JError::raiseWarning(500, $config->getError()); + } + } + + if(!$count) + { + $msg = JText::_('COM_JOOMGALLERY_CONFIGS_MSG_ERROR_DELETING'); + $type = 'error'; + } + else + { + $type = 'message'; + $msg = JText::plural('COM_JOOMGALLERY_CONFIGS_MSG_ROWS_DELETED', $count); + } + + $this->setRedirect($this->_ambit->getRedirectUrl(), $msg, $type); + } + + /** + * Moves the order of a config row + * + * @return void + * @since 2.0 + */ + public function order() + { + $cid = JRequest::getVar('cid', array(), 'post', 'array'); + + // Direction + $dir = 1; + $task = JRequest::getCmd('task'); + if($task == 'orderup') + { + $dir = -1; + } + + if(isset($cid[0])) + { + $row = JTable::getInstance('joomgalleryconfig', 'Table'); + $row->load((int)$cid[0]); + $row->move($dir); + //$row->reorder(); + } + + $this->setRedirect($this->_ambit->getRedirectUrl()); + } + + /** + * Saves the order of the config rows + * + * @return void + * @since 2.0 + */ + public function saveOrder() + { + $cid = JRequest::getVar('cid', array(0), 'post', 'array'); + $order = JRequest::getVar('order', array(0), 'post', 'array'); + + // Create and load the categories table object + $row = JTable::getInstance('joomgalleryconfig', 'Table'); + + // Update the ordering for items in the cid array + for($i = 0; $i < count($cid); $i ++) + { + $row->load((int)$cid[$i]); + if($row->ordering != $order[$i]) + { + $row->ordering = $order[$i]; + $row->check(); + if(!$row->store()) + { + JError::raiseError( 500, $this->_db->getErrorMsg()); + + return false; + } + } + } + + //$row->reorder(); + + $msg = JText::_('COM_JOOMGALLERY_COMMON_MSG_NEW_ORDERING_SAVED'); + $this->setRedirect($this->_ambit->getRedirectUrl(), $msg); + } + + /** + * Cancel editing or creating a config row + * + * @access public + * @return void + * @since 2.0 + */ + function cancel() + { + $this->setRedirect($this->_ambit->getRedirectUrl()); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/controllers/control.php b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/control.php new file mode 100644 index 00000000..d543730a --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/control.php @@ -0,0 +1,129 @@ +setRedirect('index.php?option='._JOOM_OPTION, JText::_('COM_JOOMGALLERY_ADMENU_MSG_ERROR_FETCHING_ZIP'), 'error'); + } + else + { + JoomExtensions::autoUpdate($extensions[$extension]['updatelink']); + } + + // Tell JoomGallery to do the update check again after the update + $mainframe = JFactory::getApplication(); + $mainframe->setUserState('joom.update.checked', null); + } + + /** + * Installs a new extension for JoomGallery + * + * The cURL library needs to be installed on the server for this. + * + * @access public + * @return void + * @since 1.5.5 + */ + function install() + { + $extension = JRequest::getCmd('extension', 0, 'get'); + $extensions = JoomExtensions::getAvailableExtensions(); + + if(!isset($extensions[$extension]['updatelink']) || !extension_loaded('curl')) + { + $this->setRedirect('index.php?option='._JOOM_OPTION, JText::_('COM_JOOMGALLERY_ADMENU_MSG_ERROR_FETCHING_ZIP'), 'error'); + } + else + { + JoomExtensions::autoUpdate($extensions[$extension]['updatelink']); + } + } + + /** + * Uses the installer of Joomla! in order to install an extension + * + * @access public + * @return void + * @since 3.0 + */ + function doInstallation() + { + $mainframe = JFactory::getApplication(); + + JFactory::getLanguage()->load('com_installer'); + + $installer = JInstaller::getInstance(); + if(!$installer->install($this->_ambit->get('temp_path').'update')) + { + // There was an error installing the package + $result = false; + if(is_object($installer->manifest)) + { + $msg = JText::sprintf('COM_INSTALLER_INSTALL_ERROR', JText::_('COM_INSTALLER_TYPE_TYPE_'.strtoupper($installer->manifest->attributes()->type))); + } + } + else + { + // Package installed sucessfully + $msg = JText::sprintf('COM_INSTALLER_INSTALL_SUCCESS', JText::_('COM_INSTALLER_TYPE_TYPE_'.strtoupper($installer->manifest->attributes()->type))); + $result = true; + } + + $mainframe->setUserState('joom.control.message', $installer->message); + $mainframe->setUserState('joom.control.extension_message', $installer->get('extension_message')); + + $this->setRedirect($this->_ambit->getRedirectUrl(), $msg, $result ? 'message' : 'error'); + } +} diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/controllers/cssedit.php b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/cssedit.php new file mode 100644 index 00000000..eac88ac5 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/cssedit.php @@ -0,0 +1,127 @@ +authorise('core.admin', _JOOM_OPTION)) + { + $this->setRedirect(JRoute::_($this->_ambit->getRedirectUrl(''), false), 'You are not allowed to configure this component', 'notice'); + $this->redirect(); + } + + // Set view + JRequest::setVar('view', 'cssedit'); + + $this->file = JPATH_ROOT.'/media/joomgallery/css/joom_local.css'; + + // Register task + $this->registerTask('apply', 'save'); + } + + /** + * Saves the CSS file + * + * @access public + * @return void + * @since 1.5.5 + */ + function save() + { + jimport('joomla.filesystem.file'); + + $content = stripcslashes(JRequest::getVar('csscontent')); + + if(!$content) + { + $this->setRedirect($this->_ambit->getRedirectUrl(), JText::_('COM_JOOMGALLERY_CSSMAN_MSG_EMPTY'), 'notice'); + return; + } + + if(JFile::write($this->file, $content)) + { + $controller = ''; + if(JRequest::getCmd('task') == 'apply') + { + $controller = 'cssedit'; + } + + $this->setRedirect($this->_ambit->getRedirectUrl($controller), JText::_('COM_JOOMGALLERY_CSSMAN_MSG_CSS_SAVED')); + + } + else + { + $this->setRedirect($this->_ambit->getRedirectUrl(), JText::_('COM_JOOMGALLERY_CSSMAN_CSS_ERROR_WRITING').$this->file, 'error'); + } + } + + /** + * Deletes CSS file + * + * @access public + * @return void + * @since 1.5.5 + */ + function remove() + { + jimport('joomla.filesystem.file'); + + if(JFile::delete($this->file)) + { + $this->setRedirect($this->_ambit->getRedirectUrl(''), JText::_('COM_JOOMGALLERY_CSSMAN_MSG_CSS_DELETED')); + } + else + { + $this->setRedirect($this->_ambit->getRedirectUrl(''), JText::_('COM_JOOMGALLERY_CSSMAN_CSS_ERROR_DELETING').$this->file, 'error'); + } + } + + /** + * Cancel editing or creating the CSS file + * + * @access public + * @return void + * @since 1.5.5 + */ + function cancel() + { + $this->setRedirect($this->_ambit->getRedirectUrl('')); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/controllers/favourites.php b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/favourites.php new file mode 100644 index 00000000..1391d308 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/favourites.php @@ -0,0 +1,62 @@ +getModel('favourites'); + if(!$model->reset()) + { + $this->setRedirect($this->_ambit->getRedirectUrl('maintenance&tab=favourites'), $model->getError(), 'error'); + } + else + { + $this->setRedirect($this->_ambit->getRedirectUrl('maintenance&tab=favourites'), JText::_('COM_JOOMGALLERY_MAIMAN_FV_MSG_ALL_FAVOURITES_DELETED')); + } + } + + /** + * Synchronizes the entries in the users table of JoomGallery + * with users registered and deletes all zips of favourites. + * + * @return void + * @since 2.0 + */ + public function synchronize() + { + $model = $this->getModel('favourites'); + if(!$model->synchronize()) + { + $this->setRedirect($this->_ambit->getRedirectUrl('maintenance&tab=favourites'), $model->getError(), 'error'); + } + else + { + $this->setRedirect($this->_ambit->getRedirectUrl('maintenance&tab=favourites'), JText::_('COM_JOOMGALLERY_MAIMAN_FV_MSG_FAVOURITES_SYNCHRONIZED')); + } + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/controllers/ftpupload.php b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/ftpupload.php new file mode 100644 index 00000000..c343fbe1 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/ftpupload.php @@ -0,0 +1,94 @@ +_config->get('jg_disableunrequiredchecks') && !count(JoomHelper::getAuthorisedCategories('joom.upload'))) + { + $this->setRedirect(JRoute::_($this->_ambit->getRedirectUrl('categories'), false), JText::_('No categories found into which you are allowed to upload'), 'notice'); + + return; + } + + parent::display($cachable, $urlparams); + } + + /** + * Uploads the selected images + * + * @return void + * @since 1.5.5 + */ + public function upload() + { + require_once JPATH_COMPONENT.'/helpers/upload.php'; + $uploader = new JoomUpload(); + if($uploader->upload(JRequest::getCmd('type', 'ftp'))) + { + $msg = JText::_('COM_JOOMGALLERY_UPLOAD_MSG_SUCCESSFULL'); + $url = $this->_ambit->getRedirectUrl(); + + // Set custom redirect if we are asked for that + if($redirect = JRequest::getVar('redirect', '', '', 'base64')) + { + $url_decoded = base64_decode($redirect); + if(JURI::isInternal($url)) + { + $url = $url_decoded; + } + } + + $this->setRedirect(JRoute::_($url, false), $msg); + } + else + { + if($error = $uploader->getError()) + { + $this->setRedirect($this->_ambit->getRedirectUrl(), $error, 'error'); + } + } + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/controllers/help.php b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/help.php new file mode 100644 index 00000000..45bde4a3 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/help.php @@ -0,0 +1,69 @@ +_config->get('jg_checkupdate') || !$language || !extension_loaded('curl')) + { + $link = base64_decode(JRequest::getCmd('downloadlink')); + $this->setRedirect($this->_ambit->getRedirectUrl(), JText::sprintf('COM_JOOMGALLERY_ADMENU_MSG_ERROR_FETCHING_LANGUAGE_ZIP', $link), 'error'); + } + else + { + $extensions = JoomExtensions::getAvailableExtensions(); + $url = $extensions['JoomGallery']['updatelink']; + + $url = substr($url, 0, strrpos($url, '/') + 1); + $url = str_replace('component/', '', $url); + $url .= 'languages/'.$language.'.com_joomgallery.zip'; + + JoomExtensions::autoUpdate($url); + } + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/controllers/images.json.php b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/images.json.php new file mode 100644 index 00000000..794c29a8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/images.json.php @@ -0,0 +1,88 @@ +authorise('core.edit.state', _JOOM_OPTION.'.image.'.$cid[$i])) + { + continue; + } + + $row->load((int)$cid[$i]); + if($row->ordering != $order[$i]) + { + $row->ordering = $order[$i]; + if(!$row->store()) + { + break; + } + + // Remember the categories for reordering + $condition = 'catid = '.(int) $row->catid; + $found = false; + foreach($conditions as $cond) + { + if($cond == $condition) + { + $found = true; + break; + } + } + + if(!$found) + { + $conditions[] = $condition; + } + } + } + + // Execute reorder for each category + foreach($conditions as $cond) + { + $row->reorder($cond); + } + + echo new JJsonResponse(); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/controllers/images.php b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/images.php new file mode 100644 index 00000000..75c5fd56 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/images.php @@ -0,0 +1,797 @@ +registerTask('new', 'edit'); + $this->registerTask('apply', 'save'); + $this->registerTask('save2new', 'save'); + $this->registerTask('save2copy', 'save'); + $this->registerTask('unpublish', 'publish'); + $this->registerTask('unfeature', 'feature'); + $this->registerTask('reject', 'approve'); + $this->registerTask('accesspublic', 'access'); + $this->registerTask('accessregistered', 'access'); + $this->registerTask('accessspecial', 'access'); + $this->registerTask('orderup', 'order'); + $this->registerTask('orderdown', 'order'); + } + + /** + * Publishes or unpublishes one or more images + * + * @return void + * @since 1.5.5 + */ + public function publish() + { + // Initialize variables + $cid = JRequest::getVar('cid', array(), 'post', 'array'); + $task = JRequest::getCmd('task'); + $publish = (int)($task == 'publish'); + + if(empty($cid)) + { + $this->setRedirect($this->_ambit->getRedirectUrl(), JText::_('COM_JOOMGALLERY_COMMON_MSG_NO_IMAGES_SELECTED')); + $this->redirect(); + } + + $unchanged_images = 0; + foreach($cid as $key => $id) + { + // Prune images for which we aren't allowed to change the state + if(!JFactory::getUser()->authorise('core.edit.state', _JOOM_OPTION.'.image.'.$id)) + { + unset($cid[$key]); + $unchanged_images++; + } + } + + if($unchanged_images) + { + JError::raiseNotice(403, JText::plural('COM_JOOMGALLERY_IMGMAN_ERROR_EDITSTATE_NOT_PERMITTED', $unchanged_images)); + } + + $model = $this->getModel('images'); + if($count = $model->publish($cid, $publish)) + { + if($count != 1) + { + $msg = JText::sprintf($publish ? 'COM_JOOMGALLERY_IMGMAN_MSG_IMAGES_PUBLISHED' : 'COM_JOOMGALLERY_IMGMAN_MSG_IMAGES_UNPUBLISHED', $count); + } + else + { + $msg = JText::_($publish ? 'COM_JOOMGALLERY_IMGMAN_MSG_IMAGE_PUBLISHED' : 'COM_JOOMGALLERY_IMGMAN_MSG_IMAGE_UNPUBLISHED'); + } + $this->setRedirect($this->_ambit->getRedirectUrl(), $msg); + } + else + { + $msg = JText::_('COM_JOOMGALLERY_COMMON_MSG_ERROR_PUBLISHING_UNPUBLISHING'); + $this->setRedirect($this->_ambit->getRedirectUrl(), $msg, 'error'); + } + } + + /** + * Features or unfeatures one or more images + * + * @return void + * @since 3.3 + */ + public function feature() + { + // Initialize variables + $cid = JRequest::getVar('cid', array(), 'post', 'array'); + $task = JRequest::getCmd('task'); + $feature = (int)($task == 'feature'); + + if(empty($cid)) + { + $this->setRedirect($this->_ambit->getRedirectUrl(), JText::_('COM_JOOMGALLERY_COMMON_MSG_NO_IMAGES_SELECTED')); + $this->redirect(); + } + + $unchanged_images = 0; + foreach($cid as $key => $id) + { + // Prune images for which we aren't allowed to change the state + if(!JFactory::getUser()->authorise('core.edit.state', _JOOM_OPTION.'.image.'.$id)) + { + unset($cid[$key]); + $unchanged_images++; + } + } + + if($unchanged_images) + { + JError::raiseNotice(403, JText::plural('COM_JOOMGALLERY_IMGMAN_ERROR_EDITSTATE_NOT_PERMITTED', $unchanged_images)); + } + + $model = $this->getModel('images'); + if($count = $model->publish($cid, $feature, 'feature')) + { + if($count != 1) + { + $msg = JText::sprintf($feature ? 'COM_JOOMGALLERY_IMGMAN_MSG_IMAGES_FEATURED' : 'COM_JOOMGALLERY_IMGMAN_MSG_IMAGES_UNFEATURED', $count); + } + else + { + $msg = JText::_($feature ? 'COM_JOOMGALLERY_IMGMAN_MSG_IMAGE_FEATURED' : 'COM_JOOMGALLERY_IMGMAN_MSG_IMAGE_UNFEATURED'); + } + $this->setRedirect($this->_ambit->getRedirectUrl(), $msg); + } + else + { + $msg = JText::_('COM_JOOMGALLERY_COMMON_MSG_ERROR_FEATURING_UNFEATURING'); + $this->setRedirect($this->_ambit->getRedirectUrl(), $msg, 'error'); + } + } + + /** + * Approves or rejects one or more images + * + * @return void + * @since 1.5.5 + */ + public function approve() + { + // Initialize variables + $cid = JRequest::getVar('cid', array(), 'post', 'array'); + $task = JRequest::getCmd('task'); + $publish = -1; + if($task == 'approve') + { + $publish = 1; + } + + if(empty($cid)) + { + $this->setRedirect($this->_ambit->getRedirectUrl(), JText::_('COM_JOOMGALLERY_COMMON_MSG_NO_IMAGES_SELECTED')); + $this->redirect(); + } + + $unchanged_images = 0; + foreach($cid as $key => $id) + { + // Prune images for which we aren't allowed to change the state + if(!JFactory::getUser()->authorise('core.edit.state', _JOOM_OPTION.'.image.'.$id)) + { + unset($cid[$key]); + $unchanged_images++; + } + } + + if($unchanged_images) + { + $this->_mainframe->enqueueMessage(JText::plural('COM_JOOMGALLERY_IMGMAN_ERROR_EDITSTATE_NOT_PERMITTED', $unchanged_images), 'notice'); + } + + $model = $this->getModel('images'); + if($count = $model->publish($cid, $publish, 'approve')) + { + if($count != 1) + { + $msg = JText::sprintf($publish == 1 ? 'COM_JOOMGALLERY_IMGMAN_MSG_IMAGES_APPROVED' : 'COM_JOOMGALLERY_IMGMAN_MSG_IMAGES_REJECTED', $count); + } + else + { + $msg = JText::_($publish == 1 ? 'COM_JOOMGALLERY_IMGMAN_MSG_IMAGE_APPROVED' : 'COM_JOOMGALLERY_IMGMAN_MSG_IMAGE_REJECTED'); + + // Send message about rejection if a message was specified + if($task == 'reject' && $message = JRequest::getString('message')) + { + $model->sendRejectionMessage($cid[0], $message); + } + } + + $this->setRedirect($this->_ambit->getRedirectUrl(), $msg); + } + else + { + $msg = JText::_('COM_JOOMGALLERY_COMMON_MSG_ERROR_APPROVING_REJECTING'); + $this->setRedirect($this->_ambit->getRedirectUrl(), $msg, 'error'); + } + } + + /** + * Removes one or more images + * + * @return void + * @since 1.5.5 + */ + public function remove() + { + $model = $this->getModel('images'); + + $cid = JRequest::getVar('cid', array(), 'post', 'array'); + $unaffected_images = 0; + foreach($cid as $key => $id) + { + // Prune images which we aren't allowed to delete + if(!JFactory::getUser()->authorise('core.delete', _JOOM_OPTION.'.image.'.$id)) + { + unset($cid[$key]); + $unaffected_images++; + } + } + + JRequest::setVar('cid', $cid); + + if($unaffected_images) + { + JLog::add(JText::plural('COM_JOOMGALLERY_IMGMAN_ERROR_DELETE_NOT_PERMITTED', $unaffected_images), JLog::WARNING, 'jerror'); + } + + if(!count($cid)) + { + $this->setRedirect($this->_ambit->getRedirectUrl()); + + return; + } + + try + { + $count = $model->delete($cid); + + if($count == 1) + { + $msg = JText::_('COM_JOOMGALLERY_IMGMAN_MSG_IMAGE_DELETED'); + } + else + { + $msg = JText::sprintf('COM_JOOMGALLERY_IMGMAN_MSG_IMAGES_DELETED', $count); + } + + // Some messages are enqueued by the model + $this->setRedirect($this->_ambit->getRedirectUrl(), $msg); + } + catch(RuntimeException $e) + { + $this->setRedirect($this->_ambit->getRedirectUrl(), $e->getMessage(), 'error'); + } + } + + /** + * Displays the edit form for one or multiple images + * + * @return void + * @since 1.5.5 + */ + public function edit() + { + $cid = JRequest::getVar('cid', array(), '', 'array'); + if(count($cid) <= 1) + { + if(count($cid)) + { + $exploded = explode(',', $cid[0]); + if(count($exploded) > 1) + { + JRequest::setVar('cid', $exploded); + JRequest::setVar('view', 'editimages'); + } + else + { + JRequest::setVar('view', 'image'); + } + } + else + { + JRequest::setVar('view', 'image'); + } + } + else + { + JRequest::setVar('view', 'editimages'); + } + + JRequest::setVar('layout', 'form'); + JRequest::setVar('hidemainmenu', 1); + + parent::display(); + } + + /** + * Saves one or more images + * + * @return void + * @since 1.5.5 + */ + public function save() + { + $model = $this->getModel('image'); + + $data = JRequest::get('post', 2); + + // Editing more than one image? + if(isset($data['cids'])) + { + // Selected images + $cids_string = $data['cids']; + $cids = explode(',', $cids_string); + + // We need selected fields + if(!isset($data['change'])) + { + $this->setRedirect($this->_ambit->getRedirectUrl(null, implode(',', $cids)), JText::_('COM_JOOMGALLERY_IMGMAN_MSG_NO_BOXES_FOR_EDITING_CHECKED'), 'notice'); + return; + } + + // Selected fields to edit + $change = $data['change']; + + // Get start counter for consecutive numbering of image title + $imgtitlestartcounter = (int) $data['imgtitlestartcounter']; + $imgname_separator = JText::_('COM_JOOMGALLERY_IMGMAN_IMAGENAME_SEPARATOR'); + + $changeable_fields = array('imgtitle', 'catid', 'access', 'imgtext', 'owner', 'imgauthor', 'clearvotes', + 'cleardownloads', 'clearhits', 'published', 'approved', 'hidden', 'ordering', 'metakey', 'metadesc'); + $state_fields = array('published', 'approved', 'hidden', 'ordering'); + + // Delete all unselected and unchangeable fields + foreach($data as $key => $value) + { + if(!in_array($key, $change) || !in_array($key, $changeable_fields)) + { + unset($data[$key]); + } + } + + // Save each image + $return = array(); + $count = 0; + $imgtitle = isset($data['imgtitle']) ? $data['imgtitle'] : ''; + foreach($cids as $cid) + { + // Add consecutive number in image title + if($imgtitlestartcounter > 0 && !empty($imgtitle)) + { + $data['imgtitle'] = sprintf('%s'.$imgname_separator.'%d', $imgtitle, $imgtitlestartcounter++); + } + + $cloned_data = $data; + + // Delete state fields if editing the state is not allowed + if(!JFactory::getUser()->authorise('core.edit.state', _JOOM_OPTION.'.image.'.$cid)) + { + foreach($state_fields as $field) + { + if(isset($cloned_data[$field])) + { + unset($cloned_data[$field]); + } + } + } + + // Check whether images shall be moved or copied + if(isset($cloned_data['catid']) && JRequest::getCmd('movecopy') == 'copy') + { + $orig_img = (array) $this->_ambit->getImgObject($cid); + + $orig_img['thumb_catid'] = $orig_img['catid']; + $orig_img['detail_catid'] = $orig_img['catid']; + + $orig_img['alias'] = ''; + + $orig_img['copy_original'] = false; + if(is_file($this->_ambit->getImg('orig_path', (object) $orig_img))) + { + $orig_img['copy_original'] = true; + } + + foreach($cloned_data as $key => $value) + { + $orig_img[$key] = $value; + } + + // Set image ID back so that the model creates new images + $orig_img['id'] = 0; + $orig_img['cid'] = 0; + + $cloned_data = $orig_img; + } + else + { + $cloned_data['cid'] = $cid; + } + + if($model->store($cloned_data)) + { + $count++; + } + else + { + JError::raiseWarning(100, $model->getError()); + } + } + + if($count) + { + $this->setRedirect($this->_ambit->getRedirectUrl(null, implode(',', $cids)), JText::plural('COM_JOOMGALLERY_IMGMAN_MSG_IMAGES_SAVED', $count)); + } + else + { + $this->setRedirect($this->_ambit->getRedirectUrl(), JText::sprintf('COM_JOOMGALLERY_IMGMAN_MSG_ERROR_SAVING_IMAGES'), 'error'); + } + + return; + } + + if(JRequest::getCmd('task') == 'save2copy') + { + // Reset the ID and then treat the request as for apply. + // This way a new image will be created and after that + // it will be displayed right away + JRequest::setVar('cid', 0); + JRequest::setVar('task', 'apply'); + } + + // Editing only one image + if($cid = $model->store()) + { + if(JRequest::getCmd('task') == 'save2new') + { + // Reset the ID after storing so that we + // will be redirected to an empty form + JRequest::setVar('task', 'apply'); + $cid = 0; + } + + $msg = JText::_('COM_JOOMGALLERY_IMGMAN_MSG_IMAGE_SAVED'); + $this->setRedirect($this->_ambit->getRedirectUrl(null, $cid), $msg); + } + else + { + $msg = $model->getError(); + $this->setRedirect($this->_ambit->getRedirectUrl(), $msg, 'error'); + } + } + + /** + * Moves the order of an image + * + * @return void + * @since 1.5.5 + */ + public function order() + { + $cid = JRequest::getVar('cid', array(), 'post', 'array'); + + // Direction + $dir = 1; + $task = JRequest::getCmd('task'); + if($task == 'orderup') + { + $dir = -1; + } + + if(isset($cid[0])) + { + if(!JFactory::getUser()->authorise('core.edit.state', _JOOM_OPTION.'.image.'.$cid[0])) + { + $msg = JText::_('COM_JOOMGALLERY_IMGMAN_ERROR_EDITSTATE_NOT_PERMITTED'); + $this->setRedirect($this->_ambit->getRedirectUrl(), $msg, 'notice'); + + return; + } + + $row = JTable::getInstance('joomgalleryimages', 'Table'); + $row->load((int)$cid[0]); + $row->move($dir, 'catid = '.$row->catid); + $row->reorder('catid = '.$row->catid); + } + + $this->setRedirect($this->_ambit->getRedirectUrl()); + } + + /** + * Saves the order of the images + * + * @return void + * @since 1.5.5 + */ + public function saveOrder() + { + $cid = JRequest::getVar('cid', array(), 'post', 'array'); + $order = JRequest::getVar('order', array (0), 'post', 'array'); + $user = JFactory::getUser(); + + // Create and load the images table object + $row = JTable::getInstance('joomgalleryimages', 'Table'); + + // Update the ordering for items in the cid array + $unchanged_images = 0; + for($i = 0; $i < count($cid); $i ++) + { + if(!$user->authorise('core.edit.state', _JOOM_OPTION.'.image.'.$cid)) + { + $unchanged_images++; + continue; + } + + $row->load((int)$cid[$i]); + if($row->ordering != $order[$i]) + { + $row->ordering = $order[$i]; + if(!$row->store()) + { + JError::raiseError(500, $this->_db->getErrorMsg()); + return false; + } + } + } + + if($unchanged_images) + { + JError::raiseNotice(403, JText::plural('COM_JOOMGALLERY_IMGMAN_ERROR_EDITSTATE_NOT_PERMITTED', $unchanged_images)); + } + + $row->reorderAll(); + + $msg = JText::_('COM_JOOMGALLERY_COMMON_MSG_NEW_ORDERING_SAVED'); + $this->setRedirect($this->_ambit->getRedirectUrl(), $msg); + } + + /** + * Displays the move form + * + * @return void + * @since 1.5.5 + */ + public function showmove() + { + JRequest::setVar('view', 'move'); + JRequest::setVar('hidemainmenu', 1); + + parent::display(); + } + + /** + * Moves images to another category + * + * @return void + * @since 1.5.5 + */ + public function move() + { + $cid = JRequest::getVar('cid', array(), 'post', 'array'); + $catid = JRequest::getInt('catid'); + + if(!count($cid)) + { + $this->setRedirect($this->_ambit->getRedirectUrl(), JText::_('COM_JOOMGALLERY_COMMON_MSG_NO_IMAGES_SELECTED'), 'notice'); + $this->redirect(); + } + if(!$catid) + { + $this->setRedirect($this->_ambit->getRedirectUrl(), JText::_('COM_JOOMGALLERY_IMGMAN_MSG_NO_CATEGORY_SELECTED'), 'notice'); + $this->redirect(); + } + + $user = JFactory::getUser(); + + $count = 0; + $unaffected_images = 0; + $model = $this->getModel('image'); + foreach($cid as $id) + { + if(!$user->authorise('joom.upload', _JOOM_OPTION.'.category.'.$catid)) + { + $unaffected_images++; + continue; + } + + if($model->moveImage($id, $catid)) + { + $count++; + } + } + + if($unaffected_images) + { + JError::raiseNotice(403, JText::plural('COM_JOOMGALLERY_IMGMAN_ERROR_MOVE_NOT_PERMITTED', $unaffected_images)); + } + + if($count) + { + if($count == 1) + { + $this->setRedirect($this->_ambit->getRedirectUrl(), JText::_('COM_JOOMGALLERY_IMGMAN_MSG_IMAGE_MOVED')); + } + else + { + $this->setRedirect($this->_ambit->getRedirectUrl(), JText::sprintf('COM_JOOMGALLERY_IMGMAN_MSG_IMAGES_MOVED', $count)); + } + } + else + { + $this->setRedirect($this->_ambit->getRedirectUrl()); + } + } + + /** + * Recreates thumbnails and detail images + * + * @return void + * @since 1.5.5 + */ + public function recreate() + { + $model = $this->getModel('images'); + $count = $model->recreate(); + if(!$count[0]) + { + $type = 'error'; + $msg = $model->getError(); + } + else + { + $type = 'message'; + if($count[0] == 1) + { + $msg = JText::_('COM_JOOMGALLERY_COMMON_MSG_THUMBNAIL_RECREATED'); + } + else + { + $msg = JText::sprintf('COM_JOOMGALLERY_COMMON_MSG_THUMBNAILS_RECREATED', $count[0]); + } + if($count[1]) + { + if($count[1] == 1) + { + $msg .= '
  • '.JText::_('COM_JOOMGALLERY_COMMON_MSG_IMAGE_RECREATED'); + } + else + { + $msg .= '
  • '.JText::sprintf('COM_JOOMGALLERY_COMMON_MSG_IMAGES_RECREATED', $count[1]); + } + } + } + + // Some messages are enqueued by the model + $this->setRedirect($this->_ambit->getRedirectUrl(), $msg, $type); + } + + /** + * Resets hits of an image + * + * @return void + * @since 1.5.5 + */ + public function resetHits() + { + $id = JRequest::getInt('cid'); + + if(!JFactory::getUser()->authorise('core.edit', _JOOM_OPTION.'.image.'.$id)) + { + $msg = JText::_('COM_JOOMGALLERY_IMGMAN_ERROR_EDIT_NOT_PERMITTED'); + $this->setRedirect($this->_ambit->getRedirectUrl(null, $id), $msg, 'notice'); + + return; + } + + // Instantiate and load an image table + $row = JTable::getInstance('joomgalleryimages', 'Table'); + $row->load($id); + $row->hits = 0; + $row->store(); + + JRequest::setVar('task', 'apply'); + $msg = JText::_('COM_JOOMGALLERY_IMGMAN_MSG_HITS_RESETED'); + $this->setRedirect($this->_ambit->getRedirectUrl(null, $id), $msg); + } + + /** + * Resets downloads of an image + * + * @return void + * @since 3.1 + */ + public function resetDownloads() + { + $id = JRequest::getInt('cid'); + + if(!JFactory::getUser()->authorise('core.edit', _JOOM_OPTION.'.image.'.$id)) + { + $msg = JText::_('COM_JOOMGALLERY_IMGMAN_ERROR_EDIT_NOT_PERMITTED'); + $this->setRedirect($this->_ambit->getRedirectUrl(null, $id), $msg, 'notice'); + + return; + } + + // Instantiate and load an image table + $row = JTable::getInstance('joomgalleryimages', 'Table'); + $row->load($id); + $row->downloads = 0; + $row->store(); + + JRequest::setVar('task', 'apply'); + $msg = JText::_('COM_JOOMGALLERY_IMGMAN_MSG_DOWNLOADS_RESETED'); + $this->setRedirect($this->_ambit->getRedirectUrl(null, $id), $msg); + } + + /** + * Resets votes of an image + * + * @return void + * @since 1.5.5 + */ + public function resetVotes() + { + $id = JRequest::getInt('cid'); + + if(!JFactory::getUser()->authorise('core.edit', _JOOM_OPTION.'.image.'.$id)) + { + $msg = JText::_('COM_JOOMGALLERY_IMGMAN_ERROR_EDIT_NOT_PERMITTED'); + $this->setRedirect($this->_ambit->getRedirectUrl(null, $id), $msg, 'notice'); + + return; + } + + // Instantiate and load an image table + $row = JTable::getInstance('joomgalleryimages', 'Table'); + $row->load($id); + + // Delete votes for image + $row->imgvotes = 0; + $row->imgvotesum = 0; + $query = $this->_db->getQuery(true) + ->delete(_JOOM_TABLE_VOTES) + ->where('picid = '.$row->id); + $this->_db->setQuery($query); + if(!$this->_db->query()) + { + JFactory::getApplication()->enqueueMessagge($this->_db->getErrorMsg(), 'error'); + + return false; + } + $row->store(); + + JRequest::setVar('task', 'apply'); + $msg = JText::_('COM_JOOMGALLERY_IMGMAN_MSG_VOTES_RESETED'); + $this->setRedirect($this->_ambit->getRedirectUrl(null, $id), $msg); + } + + /** + * Cancel creating, editing or moving images + * + * @return void + * @since 1.5.5 + */ + public function cancel() + { + $this->setRedirect($this->_ambit->getRedirectUrl()); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/controllers/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/controllers/jupload.php b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/jupload.php new file mode 100644 index 00000000..7a1e8573 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/jupload.php @@ -0,0 +1,71 @@ +_config->get('jg_disableunrequiredchecks') && !count(JoomHelper::getAuthorisedCategories('joom.upload'))) + { + $this->setRedirect(JRoute::_($this->_ambit->getRedirectUrl('categories'), false), JText::_('No categories found into which you are allowed to upload'), 'notice'); + + return; + } + + parent::display($cachable, $urlparams); + } + + /** + * Uploads the passed images + * + * @return void + * @since 1.5.5 + */ + public function upload() + { + require_once JPATH_COMPONENT.'/helpers/upload.php'; + $uploader = new JoomUpload(); + $uploader->upload(JRequest::getCmd('type', 'java')); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/controllers/maintenance.php b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/maintenance.php new file mode 100644 index 00000000..7f09cc8b --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/maintenance.php @@ -0,0 +1,828 @@ +authorise('core.admin', _JOOM_OPTION)) + { + $this->setRedirect(JRoute::_($this->_ambit->getRedirectUrl(''), false), 'You are not allowed to configure this component', 'notice'); + $this->redirect(); + } + + // Set view + JRequest::setVar('view', 'maintenance'); + + $this->registerTask('parsefolders', 'check'); + $this->registerTask('checkimages', 'check'); + $this->registerTask('checkcategories', 'check'); + $this->registerTask('createfilesuggestions', 'check'); + $this->registerTask('createfoldersuggestions', 'check'); + } + + /** + * Removes one or more images even if some files aren't found + * + * @return void + * @since 1.5.5 + */ + public function remove() + { + $model = $this->getModel('maintenance'); + if(!$count = $model->delete()) + { + $msg = $model->getError(); + $type = 'error'; + } + else + { + $type = 'message'; + if($count == 1) + { + $msg = JText::_('COM_JOOMGALLERY_MAIMAN_MSG_IMAGE_DELETED'); + } + else + { + $msg = JText::sprintf('COM_JOOMGALLERY_MAIMAN_MSG_IMAGES_DELETED', $count); + } + } + + // Some messages are enqueued by the model + $this->setRedirect($this->_ambit->getRedirectUrl(), $msg, $type); + } + + /** + * Removes one or more categories even if some files or + * folders aren't found or if there are still sub-categories + * + * @return void + * @since 1.5.5 + */ + public function removeCategory() + { + $model = $this->getModel('maintenance'); + if(!$count = $model->deletecategory()) + { + $msg = $model->getError(); + $type = 'error'; + } + else + { + $type = 'message'; + if($count == 1) + { + $msg = JText::_('COM_JOOMGALLERY_MAIMAN_MSG_CATEGORY_DELETED'); + } + else + { + $msg = JText::sprintf('COM_JOOMGALLERY_MAIMAN_MSG_CATEGORIES_DELETED', $count); + } + } + + // Some messages are enqueued by the model + $this->setRedirect($this->_ambit->getRedirectUrl().'&tab=categories', $msg, $type); + } + + /** + * Removes one or more categories even though there + * are still images or sub-categories in them. + * + * @return void + * @since 1.5.5 + */ + public function deleteCompletely() + { + $mainframe = JFactory::getApplication('administrator'); + $categories = $mainframe->getUserState('joom.maintenance.delete.categories'); + $images = $mainframe->getUserState('joom.maintenance.delete.images'); + + if(!$categories || !is_array($categories) || !count($categories)) + { + $this->setRedirect($this->_ambit->getRedirectUrl().'&tab=categories', JText::_('COM_JOOMGALLERY_COMMON_MSG_NO_CATEGORIES_SELECTED'), 'notice'); + return; + } + + require_once JPATH_COMPONENT.'/helpers/refresher.php'; + + $refresher = new JoomRefresher(); + + $img_count = $mainframe->getUserState('joom.maintenance.delete.img_count'); + if(is_null($img_count)) + { + $img_count = 0; + } + $cat_count = $mainframe->getUserState('joom.maintenance.delete.cat_count'); + if(is_null($cat_count)) + { + $cat_count = 0; + } + + $model = $this->getModel('maintenance'); + if($images && is_array($images) && count($images)) + { + $row = $model->getTable('joomgalleryimages'); + foreach($images as $key => $image) + { + // Check whether image still exists. + // It may have been deleted before if categories were selected + // to delete as well as their sub-categories. + if($row->load($image)) + { + JRequest::setVar('cid', array($image)); + if($model->delete(false)) + { + $img_count++; + } + + unset($images[$key]); + } + + if(!$refresher->check()) + { + $mainframe->setUserState('joom.maintenance.delete.images', $images); + $mainframe->setUserState('joom.maintenance.delete.img_count', $img_count); + $refresher->refresh(); + } + } + } + + $row = $model->getTable('joomgallerycategories'); + for($i = count($categories) - 1; $i >= 0; $i--) + { + foreach($categories[$i] as $key => $category) + { + // Check whether category still exists. + // It may have been deleted before if categories were selected + // to delete as well as their sub-categories. + if($row->load($category)) + { + JRequest::setVar('cid', array($category)); + if($model->deletecategory(false, false)) + { + $cat_count++; + } + + unset($categories[$i][$key]); + } + + if(!$refresher->check() && count($categories[0])) + { + $mainframe->setUserState('joom.maintenance.delete.categories', $categories); + $mainframe->setUserState('joom.maintenance.delete.img_count', $img_count); + $mainframe->setUserState('joom.maintenance.delete.cat_count', $cat_count); + $refresher->refresh(); + } + } + } + + if($img_count) + { + if($img_count == 1) + { + $msg = JText::_('COM_JOOMGALLERY_MAIMAN_MSG_IMAGE_DELETED'); + } + else + { + $msg = JText::sprintf('COM_JOOMGALLERY_MAIMAN_MSG_IMAGES_DELETED', $img_count); + } + $mainframe->enqueueMessage($msg); + } + + if($cat_count) + { + if($cat_count == 1) + { + $msg = JText::_('COM_JOOMGALLERY_MAIMAN_MSG_CATEGORY_DELETED'); + } + else + { + $msg = JText::sprintf('COM_JOOMGALLERY_MAIMAN_MSG_CATEGORIES_DELETED', $cat_count); + } + $mainframe->enqueueMessage($msg); + } + + // Reset all user states of this task + $mainframe->setUserState('joom.maintenance.delete', null); + + $this->setRedirect($this->_ambit->getRedirectUrl().'&tab=categories'); + } + + /** + * Resets aliases of all images and categories + * + * @return void + * @since 1.5.5 + */ + public function setAlias() + { + $model = $this->getModel('maintenance'); + $count = $model->resetAliases(); + if(!$count[0]) + { + $type = 'error'; + $msg = $model->getError(); + } + else + { + $type = 'message'; + $msg = JText::_('COM_JOOMGALLERY_MAIMAN_MSG_CATEGORIES_ALIAS_RESET'); + if($count[0]) + { + $msg .= '
  • '.JText::_('COM_JOOMGALLERY_MAIMAN_MSG_IMAGES_ALIAS_RESET'); + } + } + + $this->setRedirect($this->_ambit->getRedirectUrl(), $msg, $type); + } + + /** + * Sets a new user as the owner of the selected images + * + * @return void + * @since 1.5.5 + */ + public function setUser() + { + $model = $this->getModel('maintenance'); + $count = $model->setUser(); + if(!$count) + { + $type = 'error'; + $msg = $model->getError(); + } + else + { + $type = 'message'; + if($count == 1) + { + $msg = JText::_('COM_JOOMGALLERY_MAIMAN_MSG_IMAGE_USER_SET'); + } + else + { + $msg = JText::sprintf('COM_JOOMGALLERY_MAIMAN_MSG_IMAGES_USER_SET', $count); + } + } + + // Some messages are enqueued by the model + $this->setRedirect($this->_ambit->getRedirectUrl(), $msg, $type); + } + + /** + * Sets a new user as the owner of the selected categories + * + * @return void + * @since 1.5.5 + */ + public function setCategoryUser() + { + $model = $this->getModel('maintenance'); + $count = $model->setCategoryUser(); + if(!$count) + { + $type = 'error'; + $msg = $model->getError(); + } + else + { + $type = 'message'; + if($count == 1) + { + $msg = JText::_('COM_JOOMGALLERY_MAIMAN_CT_MSG_CATEGORY_USER_SET'); + } + else + { + $msg = JText::sprintf('COM_JOOMGALLERY_MAIMAN_CT_MSG_CATEGORIES_USER_SET', $count); + } + } + + // Some messages are enqueued by the model + $this->setRedirect($this->_ambit->getRedirectUrl().'&tab=categories', $msg, $type); + } + + /** + * Moves orphaned files to their suggested correct folder + * + * @return void + * @since 1.5.5 + */ + public function addOrphan() + { + $tab = JRequest::getCmd('tab'); + + if($tab == 'orphans') + { + $tab = '&tab=orphans'; + } + else + { + $tab = ''; + } + + $model = $this->getModel('maintenance'); + if(!$count = $model->addOrphan()) + { + $type = 'error'; + $msg = $model->getError(); + } + else + { + $type = 'message'; + + if($count == 1) + { + $msg = JText::_('COM_JOOMGALLERY_MAIMAN_MSG_ORPHAN_SUCCESSFULLY_ADDED'); + } + else + { + $msg = JText::sprintf('COM_JOOMGALLERY_MAIMAN_MSG_ORPHANS_SUCCESSFULLY_ADDED', $count); + } + } + + // Some messages are enqueued by the model + $this->setRedirect($this->_ambit->getRedirectUrl().$tab, $msg, $type); + } + + /** + * Filters selected images and moves all orphaned files to their suggested correct folder + * + * @return void + * @since 1.5.5 + */ + public function addOrphans() + { + $tab = JRequest::getCmd('tab'); + + if($tab == 'orphans') + { + $tab = '&tab=orphans'; + } + else + { + $tab = ''; + } + + $model = $this->getModel('maintenance'); + if(!$count = $model->addOrphans()) + { + $type = 'error'; + $msg = $model->getError(); + } + else + { + $type = 'message'; + + if($count == 1) + { + $msg = JText::_('COM_JOOMGALLERY_MAIMAN_MSG_ORPHAN_SUCCESSFULLY_ADDED'); + } + else + { + $msg = JText::sprintf('COM_JOOMGALLERY_MAIMAN_MSG_ORPHANS_SUCCESSFULLY_ADDED', $count); + } + } + + // Some messages are enqueued by the model + $this->setRedirect($this->_ambit->getRedirectUrl().$tab, $msg, $type); + } + + /** + * Moves orphaned files to their suggested correct folder + * + * @return void + * @since 1.5.5 + */ + public function addOrphanedFolder() + { + $tab = JRequest::getCmd('tab'); + + if($tab == 'folders') + { + $tab = '&tab=folders'; + } + else + { + $tab = '&tab=categories'; + } + + $model = $this->getModel('maintenance'); + if(!$count = $model->addOrphanedFolder()) + { + $type = 'error'; + $msg = $model->getError(); + } + else + { + $type = 'message'; + + if($count == 1) + { + $msg = JText::_('COM_JOOMGALLERY_MAIMAN_OF_MSG_FOLDER_SUCCESSFULLY_ADDED'); + } + else + { + $msg = JText::sprintf('COM_JOOMGALLERY_MAIMAN_OF_MSG_FOLDERS_SUCCESSFULLY_ADDED', $count); + } + } + + // Some messages are enqueued by the model + $this->setRedirect($this->_ambit->getRedirectUrl().$tab, $msg, $type); + } + + /** + * Filters selected images and moves all orphaned files to their suggested correct folder + * + * @return void + * @since 1.5.5 + */ + public function addOrphanedFolders() + { + $tab = JRequest::getCmd('tab'); + + if($tab == 'folders') + { + $tab = '&tab=folders'; + } + else + { + $tab = '&tab=categories'; + } + + $model = $this->getModel('maintenance'); + if(!$count = $model->addOrphanedFolders()) + { + $type = 'error'; + $msg = $model->getError(); + } + else + { + $type = 'message'; + + if($count == 1) + { + $msg = JText::_('COM_JOOMGALLERY_MAIMAN_OF_MSG_FOLDER_SUCCESSFULLY_ADDED'); + } + else + { + $msg = JText::sprintf('COM_JOOMGALLERY_MAIMAN_OF_MSG_FOLDERS_SUCCESSFULLY_ADDED', $count); + } + } + + // Some messages are enqueued by the model + $this->setRedirect($this->_ambit->getRedirectUrl().$tab, $msg, $type); + } + + /** + * Recreates thumbnails and detail images + * + * @return void + * @since 1.5.5 + */ + public function recreate() + { + // Load the necessary image IDs + $cids = JRequest::getVar('cid', array(), '', 'array'); + + if(!count($cids)) + { + $this->setRedirect($this->_ambit->getRedirectUrl(), JText::_('COM_JOOMGALLERY_COMMON_MSG_NO_IMAGES_SELECTED'), 'error'); + return; + } + + JArrayHelper::toInteger($cids); + + $query = $this->_db->getQuery(true) + ->select('refid') + ->from($this->_db->qn(_JOOM_TABLE_MAINTENANCE)) + ->where('id IN ('.implode(',', $cids).')'); + $this->_db->setQuery($query); + if(!$cids = $this->_db->loadColumn()) + { + $this->setRedirect($this->_ambit->getRedirectUrl(), $this->_db->getErrorMsg(), 'error'); + + return; + } + + JRequest::setVar('cid', $cids); + + // Recreate the images + $model = $this->getModel('images'); + $count = $model->recreate(); + if(!$count[0] && !$count[1]) + { + $type = 'error'; + $msg = $model->getError(); + } + else + { + $type = 'message'; + $msg = ''; + /*if($count[0]) + { + if($count[0] == 1) + { + $msg = JText::_('COM_JOOMGALLERY_COMMON_MSG_THUMBNAIL_RECREATED'); + } + else + { + $msg = JText::sprintf('COM_JOOMGALLERY_COMMON_MSG_THUMBNAILS_RECREATED', $count[0]); + } + } + if($count[1]) + { + if($count[1] == 1) + { + $msg .= '
  • '.JText::_('COM_JOOMGALLERY_COMMON_MSG_IMAGE_RECREATED'); + } + else + { + $msg .= '
  • '.JText::sprintf('COM_JOOMGALLERY_COMMON_MSG_IMAGES_RECREATED', $count[1]); + } + }*/ + + foreach($count[2] as $key => $types) + { + $set = ''; + if(in_array('thumb', $types)) + { + $set = 'thumb = '.$this->_db->q($this->_ambit->getImg('thumb_url', $key)).', thumborphan = 0'; + } + if(in_array('img', $types)) + { + if($set) + { + $set .= ', '; + } + $set .= 'img = '.$this->_db->q($this->_ambit->getImg('img_url', $key)).', imgorphan = 0'; + } + + if($set) + { + $query = $this->_db->getQuery(true) + ->update($this->_db->qn(_JOOM_TABLE_MAINTENANCE)) + ->set($set) + ->where('refid = '.$key) + ->where('type = 0'); + $this->_db->setQuery($query); + if(!$this->_db->query()) + { + JError::raiseWarning(500, $this->_db->getErrorMsg()); + } + } + } + } + + // Some messages are enqueued by the model + $this->setRedirect($this->_ambit->getRedirectUrl(), $msg, $type); + } + + /** + * Removes one or more orphaned files + * + * @return void + * @since 1.5.5 + */ + public function deleteOrphan() + { + $model = $this->getModel('maintenance'); + if(!$count = $model->deleteOrphan()) + { + $msg = $model->getError(); + $type = 'error'; + } + else + { + $type = 'message'; + if($count == 1) + { + $msg = JText::_('COM_JOOMGALLERY_MAIMAN_MSG_FILE_DELETED'); + } + else + { + $msg = JText::sprintf('COM_JOOMGALLERY_MAIMAN_MSG_FILES_DELETED', $count); + } + } + + // Some messages are enqueued by the model + $this->setRedirect($this->_ambit->getRedirectUrl().'&tab=orphans', $msg, $type); + } + + /** + * Removes one or more orphaned files + * + * @return void + * @since 1.5.5 + */ + public function deleteOrphanedFolder() + { + $model = $this->getModel('maintenance'); + if(!$count = $model->deleteOrphanedFolder()) + { + $msg = $model->getError(); + $type = 'error'; + } + else + { + $type = 'message'; + if($count == 1) + { + $msg = JText::_('COM_JOOMGALLERY_MAIMAN_OF_MSG_FOLDER_DELETED'); + } + else + { + $msg = JText::sprintf('COM_JOOMGALLERY_MAIMAN_OF_MSG_FOLDERS_DELETED', $count); + } + } + + // Some messages are enqueued by the model + $this->setRedirect($this->_ambit->getRedirectUrl().'&tab=folders', $msg, $type); + } + + /** + * Executes all suggested tasks on orphaned files. + * + * Files for which corrupt images were found will be moved. + * All other files will be deleted. + * + * @return void + * @since 1.5.5 + */ + public function applySuggestions() + { + $model = $this->getModel('maintenance'); + $count = $model->applySuggestions(); + if(!$count) + { + $type = 'error'; + $msg = $model->getError(); + } + else + { + $type = 'message'; + if($count[0] == 1) + { + $msg = JText::_('COM_JOOMGALLERY_MAIMAN_MSG_ONE_ORPHAN_SUCCESSFULLY_ADDED'); + } + else + { + $msg = JText::sprintf('COM_JOOMGALLERY_MAIMAN_MSG_ORPHANS_SUCCESSFULLY_ADDED', $count[0]); + } + if($count[1] !== false) + { + if($count[1] == 1) + { + $msg .= '
  • '.JText::sprintf('COM_JOOMGALLERY_MAIMAN_MSG_ONE_FILE_DELETED'); + } + else + { + $msg .= '
  • '.JText::sprintf('COM_JOOMGALLERY_MAIMAN_MSG_FILES_DELETED', $count[1]); + } + } + } + + // Some messages are enqueued by the model + $this->setRedirect($this->_ambit->getRedirectUrl().'&tab=orphans', $msg, $type); + } + + /** + * Executes all suggested tasks on orphaned folders. + * + * Folders for which corrupt categories were found will be moved. + * All other folders will be deleted. + * + * @return void + * @since 1.5.5 + */ + public function applyFolderSuggestions() + { + $model = $this->getModel('maintenance'); + $count = $model->applyFolderSuggestions(); + if(!$count) + { + $type = 'error'; + $msg = $model->getError(); + } + else + { + $type = 'message'; + if($count[0] == 1) + { + $msg = JText::_('COM_JOOMGALLERY_MAIMAN_OF_MSG_ONE_FOLDER_ADDED'); + } + else + { + $msg = JText::sprintf('COM_JOOMGALLERY_MAIMAN_OF_MSG_FOLDERS_SUCCESSFULLY_ADDED', $count[0]); + } + if($count[1] !== false) + { + if($count[1] == 1) + { + $msg .= '
  • '.JText::sprintf('COM_JOOMGALLERY_MAIMAN_OF_MSG_ONE_FOLDER_DELETED'); + } + else + { + $msg .= '
  • '.JText::sprintf('COM_JOOMGALLERY_MAIMAN_OF_MSG_FOLDERS_DELETED', $count[1]); + } + } + } + + // Some messages are enqueued by the model + $this->setRedirect($this->_ambit->getRedirectUrl().'&tab=folders', $msg, $type); + } + + /** + * Creates new folders for categories. + * + * @return void + * @since 1.5.5 + */ + public function create() + { + $model = $this->getModel('maintenance'); + if(!$count = $model->create()) + { + $msg = $model->getError(); + $type = 'error'; + } + else + { + $type = 'message'; + if($count == 1) + { + $msg = JText::_('COM_JOOMGALLERY_MAIMAN_OF_MSG_FOLDER_CREATED'); + } + else + { + $msg = JText::sprintf('COM_JOOMGALLERY_MAIMAN_OF_MSG_FOLDERS_CREATED', $count); + } + } + + // Some messages are enqueued by the model + $this->setRedirect($this->_ambit->getRedirectUrl().'&tab=categories', $msg, $type); + } + + /** + * Searches for corrupt images and orphand files in the filesystem of JoomGallery + * + * @return void + * @since 1.5.5 + */ + public function check() + { + $model = $this->getModel('maintenancecheck'); + + $task = JRequest::getCmd('task'); + + require_once JPATH_COMPONENT.'/helpers/refresher.php'; + + // The model will redirect, too. + $model->$task(); + } + + /** + * Optimizes all database tables of JoomGallery + * + * @return void + * @since 1.5.5 + */ + public function optimize() + { + $model = $this->getModel('maintenance'); + + if(!$model->optimize()) + { + $this->setRedirect($this->_ambit->getRedirectUrl().'&tab=database', JText::_('COM_JOOMGALLERY_MAIMAN_DB_MSG_OPTIMIZATION_NOT_SUCCESSFUL'), 'error'); + } + else + { + $this->setRedirect($this->_ambit->getRedirectUrl().'&tab=database', JText::_('COM_JOOMGALLERY_MAIMAN_DB_MSG_OPTIMIZATION_SUCCESSFUL')); + } + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/controllers/migration.php b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/migration.php new file mode 100644 index 00000000..c8ee047d --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/migration.php @@ -0,0 +1,81 @@ +registerTask('check', 'migrate'); + $this->registerTask('start', 'migrate'); + } + + /** + * Migrates another gallery to JoomGallery + * + * @access public + * @return void + * @since 1.5.5 + */ + function migrate() + { + jimport('joomla.filesystem.file'); + + $migration = JRequest::getCmd('migration', ''); + $task = JRequest::getCmd('task'); + + if(!JFile::exists(JPATH_COMPONENT.'/helpers/migration/migrate'.$migration.'.php')) + { + $this->setRedirect('index.php?option='._JOOM_OPTION.'&controller=migration'); + + return; + } + + require_once JPATH_COMPONENT.'/helpers/migration/migrate'.$migration.'.php'; + $classname = 'JoomMigrate'.$migration; + $migrateclass = new $classname(); + + ob_start(); + $migrateclass->$task(); + JFactory::getApplication()->setUserState('joom.migration.output', ob_get_contents()); + ob_end_clean(); + + if($task == 'check') + { + parent::display(); + } + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/controllers/nametags.php b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/nametags.php new file mode 100644 index 00000000..4ed7379f --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/nametags.php @@ -0,0 +1,71 @@ +_db->truncateTable(_JOOM_TABLE_NAMESHIELDS); + + if($this->_db->getErrorMsg()) + { + $this->setRedirect($this->_ambit->getRedirectUrl('maintenance&tab=nametags'), $this->_db->getErrorMsg(), 'error'); + + return; + } + + $this->setRedirect($this->_ambit->getRedirectUrl('maintenance&tab=nametags'), JText::_('COM_JOOMGALLERY_MAIMAN_MSG_ALL_NAMETAGS_DELETED')); + } + + /** + * Synchronizes the nametags with users registered and existing images. + * + * Nametags of users that aren't registed any more will be deleted. + * + * @return void + * @since 1.5.5 + */ + public function synchronize() + { + // Synchronize users-nametags-images + $query = $this->_db->getQuery(true) + ->delete('n USING '._JOOM_TABLE_NAMESHIELDS.' AS n') + ->leftJoin('#__users AS u ON n.nuserid = u.id') + ->leftJoin(_JOOM_TABLE_IMAGES.' AS i ON n.npicid = i.id') + ->where('(u.id IS NULL OR i.id IS NULL)'); + $this->_db->setQuery($query); + + if(!$this->_db->query()) + { + $this->setRedirect($this->_ambit->getRedirectUrl('maintenance&tab=nametags'), $this->_db->getErrorMsg(), 'error'); + return; + } + + $this->setRedirect($this->_ambit->getRedirectUrl('maintenance&tab=nametags'), JText::_('COM_JOOMGALLERY_MAIMAN_MSG_NAMETAGS_SYNCHRONIZED')); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/controllers/upload.php b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/upload.php new file mode 100644 index 00000000..77ba535f --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/upload.php @@ -0,0 +1,94 @@ +_config->get('jg_disableunrequiredchecks') && !count(JoomHelper::getAuthorisedCategories('joom.upload'))) + { + $this->setRedirect(JRoute::_($this->_ambit->getRedirectUrl('categories'), false), JText::_('No categories found into which you are allowed to upload'), 'notice'); + + return; + } + + parent::display($cachable, $urlparams); + } + + /** + * Uploads the selected images + * + * @return void + * @since 1.5.5 + */ + public function upload() + { + require_once JPATH_COMPONENT.'/helpers/upload.php'; + $uploader = new JoomUpload(); + if($uploader->upload(JRequest::getCmd('type', 'single'))) + { + $msg = JText::_('COM_JOOMGALLERY_UPLOAD_MSG_SUCCESSFULL'); + $url = $this->_ambit->getRedirectUrl(); + + // Set custom redirect if we are asked for that + if($redirect = JRequest::getVar('redirect', '', '', 'base64')) + { + $url_decoded = base64_decode($redirect); + if(JURI::isInternal($url)) + { + $url = $url_decoded; + } + } + + $this->setRedirect(JRoute::_($url, false), $msg); + } + else + { + if($error = $uploader->getError()) + { + $this->setRedirect($this->_ambit->getRedirectUrl(), $error, 'error'); + } + } + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/controllers/votes.php b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/votes.php new file mode 100644 index 00000000..24e2e418 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/controllers/votes.php @@ -0,0 +1,107 @@ +_db->truncateTable(_JOOM_TABLE_VOTES); + + if($this->_db->getErrorMsg()) + { + $this->setRedirect($this->_ambit->getRedirectUrl('maintenance&tab=votes'), $this->_db->getErrorMsg(), 'error'); + + return; + } + + $query = $this->_db->getQuery(true) + ->update(_JOOM_TABLE_IMAGES) + ->set('imgvotes = 0') + ->set('imgvotesum = 0'); + $this->_db->setQuery($query); + + if(!$this->_db->query()) + { + $this->setRedirect($this->_ambit->getRedirectUrl('maintenance&tab=votes'), $this->_db->getErrorMsg(), 'error'); + + return; + } + + $this->setRedirect($this->_ambit->getRedirectUrl('maintenance&tab=votes'), JText::_('COM_JOOMGALLERY_MAIMAN_MSG_ALL_VOTES_DELETED')); + } + + /** + * Synchronizes the votes with users registered and exiting images. + * + * Votes of users that aren't registed any more will be deleted. + * + * @return void + * @since 1.5.5 + */ + public function synchronize() + { + // Synchronize users-votes-images + $query = $this->_db->getQuery(true) + ->delete('v USING '._JOOM_TABLE_VOTES.' AS v') + ->leftJoin('#__users AS u ON v.userid = u.id') + ->leftJoin(_JOOM_TABLE_IMAGES.' AS i ON v.picid = i.id') + ->where('v.userid != 0') + ->where('(u.id IS NULL OR i.id IS NULL)'); + $this->_db->setQuery($query); + + if(!$this->_db->query()) + { + $this->setRedirect($this->_ambit->getRedirectUrl('maintenance&tab=votes'), $this->_db->getErrorMsg(), 'error'); + return; + } + + $count_subquery = $this->_db->getQuery(true) + ->select('COUNT(*)') + ->from(_JOOM_TABLE_VOTES.' as v') + ->where('v.picid = p.id'); + + $sum_subquery = $this->_db->getQuery(true) + ->select('SUM(v.vote)') + ->from(_JOOM_TABLE_VOTES.' as v') + ->where('v.picid = p.id'); + + $query->clear() + ->update(_JOOM_TABLE_IMAGES.' AS p') + ->set('p.imgvotes = ('.$count_subquery.')') + ->set('p.imgvotesum = ('.$sum_subquery.')'); + $this->_db->setQuery($query); + + if(!$this->_db->query()) + { + $this->setRedirect($this->_ambit->getRedirectUrl('maintenance&tab=votes'), $this->_db->getErrorMsg(), 'error'); + + return; + } + + $this->setRedirect($this->_ambit->getRedirectUrl('maintenance&tab=votes'), JText::_('COM_JOOMGALLERY_MAIMAN_MSG_USERVOTES_SYNCHRONIZED')); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/helpers/adminconfig.php b/deployed/joomgallery/administrator/components/com_joomgallery/helpers/adminconfig.php new file mode 100644 index 00000000..2a63de9f --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/helpers/adminconfig.php @@ -0,0 +1,1052 @@ +getProperties(); + } + + $isNew = !$id; + + $config = JTable::getInstance('joomgalleryconfig', 'Table'); + + if(!$this->isExtended()) + { + // Update the currently selected row + $config->load($this->_id); + $id = $this->_id; + } + else + { + // Create a new row based on an existing one + if($isNew && !$existing_row) + { + $existing_row = $this->_id; + } + else + { + if(!$isNew) + { + $existing_row = $id; + } + } + + $config->load($existing_row); + + if($isNew) + { + $config->group_id = $group_id; + $config->ordering = $config->getNextOrder(); + } + } + + // Remove some values which could make the resulting row invalid + if(isset($data['group_id'])) + { + unset($data['group_id']); + } + if(isset($data['ordering'])) + { + unset($data['ordering']); + } + + $config->bind($data); + + $config->id = $id; + + if(!$config->check()) + { + return false; + } + + if(!$config->store()) + { + return false; + } + + // Publish new config values + $properties = $config->getProperties(); + foreach($properties as $key => $value) + { + $this->$key = $value; + } + + if(!$this->saveCSS()) + { + return false; + } + + return $config->id; + } + + /** + * Save joom_settings.css according to the configuration settings + * + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + public function saveCSS() + { + $icon_url = '../images/'; + + // Common settings + // Bottomed alignment of images + $jg_common_imgalign = ''; + // Gallery view + if($this->jg_imgalign > 0 && $this->jg_colcat > 1) + { + $jg_common_imgalign .= ".jg_imgalign_gal{\n"; + $jg_common_imgalign .= " height:".$this->jg_imgalign."px;\n"; + $jg_common_imgalign .= " position:relative;\n"; + $jg_common_imgalign .= "}\n"; + + $jg_common_imgalign .= ".jg_photo_container, .jg_photo_container_c, .jg_photo_container_l, .jg_photo_container_r{\n"; + $jg_common_imgalign .= " bottom:0;\n"; + $jg_common_imgalign .= " position:absolute;\n"; + $jg_common_imgalign .= " width:100%;\n"; + $jg_common_imgalign .= "}\n"; + $jg_common_imgalign .= ".jg_element_txt{\n"; + $jg_common_imgalign .= " margin-top: 10px;\n"; + $jg_common_imgalign .= "}\n"; + } + + // Category view subcategories + if($this->jg_imgalign > 0 && $this->jg_colsubcat > 1) + { + $jg_common_imgalign .= ".jg_imgalign_catsubs{\n"; + $jg_common_imgalign .= " height:".$this->jg_imgalign."px;\n"; + $jg_common_imgalign .= " position:relative;\n"; + $jg_common_imgalign .= "}\n"; + + $jg_common_imgalign .= ".jg_subcatelem_photo, .jg_subcatelem_photo_c, .jg_subcatelem_photo_l, .jg_subcatelem_photo_r{\n"; + $jg_common_imgalign .= " bottom:0;\n"; + $jg_common_imgalign .= " position:absolute;\n"; + $jg_common_imgalign .= " width:100%;\n"; + $jg_common_imgalign .= "}\n"; + } + + // Category view images + if($this->jg_imgalign > 0 && $this->jg_colnumb > 1) + { + $jg_common_imgalign .= ".jg_imgalign_catimgs{\n"; + $jg_common_imgalign .= " height:".$this->jg_imgalign."px;\n"; + $jg_common_imgalign .= " position:relative;\n"; + $jg_common_imgalign .= "}\n"; + + $jg_common_imgalign .= ".jg_catelem_photo_align{\n"; + $jg_common_imgalign .= " bottom:0;\n"; + $jg_common_imgalign .= " position:absolute;\n"; + $jg_common_imgalign .= " width:100%;\n"; + $jg_common_imgalign .= "}\n"; + } + + // Toplists/Favourites view + if($this->jg_imgalign > 0 && $this->jg_toplistcols > 1) + { + $jg_common_imgalign .= ".jg_imgalign_top{\n"; + $jg_common_imgalign .= " height:".$this->jg_imgalign."px;\n"; + $jg_common_imgalign .= " position:relative;\n"; + $jg_common_imgalign .= "}\n"; + + $jg_common_imgalign .= ".jg_topelem_photo{\n"; + $jg_common_imgalign .= " bottom:0;\n"; + $jg_common_imgalign .= " position:absolute;\n"; + $jg_common_imgalign .= " width:100%;\n"; + $jg_common_imgalign .= "}\n"; + + $jg_common_imgalign .= ".jg_imgalign_fav{\n"; + $jg_common_imgalign .= " height:".$this->jg_imgalign."px;\n"; + $jg_common_imgalign .= " position:relative;\n"; + $jg_common_imgalign .= "}\n"; + + $jg_common_imgalign .= ".jg_favelem_photo{\n"; + $jg_common_imgalign .= " bottom:0;\n"; + $jg_common_imgalign .= " position:absolute;\n"; + $jg_common_imgalign .= " width:100%;\n"; + $jg_common_imgalign .= "}\n"; + } + + // Search view + if($this->jg_imgalign > 0 && $this->jg_searchcols > 1) + { + $jg_common_imgalign .= ".jg_imgalign_search{\n"; + $jg_common_imgalign .= " height:".$this->jg_imgalign."px;\n"; + $jg_common_imgalign .= " position:relative;\n"; + $jg_common_imgalign .= "}\n"; + + $jg_common_imgalign .= ".jg_searchelem_photo{\n"; + $jg_common_imgalign .= " bottom:0;\n"; + $jg_common_imgalign .= " position:absolute;\n"; + $jg_common_imgalign .= " width:100%;\n"; + $jg_common_imgalign .= "}"; + } + + // Calculation of colum widths + // Gallery view + $colwidth_gal = floor(99 / $this->jg_colcat); + // Category view + $colwidth_cat = floor(99 / $this->jg_colnumb); + // Sub-category view + $colwidth_subcat = floor(99 / $this->jg_colsubcat); + + // Alignment of container for text and image + // if ct_align=0, alternating alignments + // jg_element_gal + $jg_gal_container = ""; + + // jg_photo_container + $jg_gal_elemimg = ""; + + // jg_element_txt + $jg_gal_elemtxt = ""; + $jg_gal_elemtxt_subs = ""; + + // Gallery view + // User defined alignment for category thumb + if($this->jg_showcatthumb == 2) + { + if($this->jg_colcat == 1) + { + $jg_gal_container = " text-align:left !important;\n"; + } + else + { + $jg_gal_container = " float:left;\n"; + } + } + // Activated random view of thumbs or no thumbs or override + // Alignment on one columned view not with float, instead text-align + //if($this->jg_showcatthumb == 1 || $this->jg_showcatthumb == 0 || $this->jg_showcatthumb == 3) + //{ + switch($this->jg_ctalign) + { + case 1: + // Left aligned + // One column -> text-align + if($this->jg_colcat == 1) + { + $jg_gal_container = " text-align:left !important;\n"; + $jg_gal_elemtxt = " text-align:left !important; \n"; + $jg_gal_elemtxt_subs = " text-align:left !important; \n"; + } + else + { + $jg_gal_container = " float:left;\n"; + $jg_gal_elemtxt = " float:left;\n"; + $jg_gal_elemtxt_subs = " float:left;\n"; + } + break; + case 2: + // Right aligned + // One column -> text-align + if($this->jg_colcat == 1 || $this->jg_catperpage == 1) + { + $jg_gal_container = " text-align:right !important;\n"; + } + else + { + $jg_gal_container = " float:right;\n"; + } + $jg_gal_elemtxt = " text-align:right !important;\n"; + $jg_gal_elemtxt_subs = " float:right;\n text-align:right !important;"; + break; + case 3: + // Centered + if ($this->jg_colcat == 1 || $this->jg_catperpage == 1) + { + $jg_gal_container = " text-align:center;\n"; + } + else + { + $jg_gal_container = " float:left;\n"; + } + $jg_gal_elemtxt = " text-align:center !important;\n"; + $jg_gal_elemtxt_subs = " text-align:center !important;\n"; + break; + + default: + // =0 alternating, classes with *_r implied right placement + // in joomgallery.css + $jg_gal_container = " float:left;\n"; + $jg_gal_elemtxt = " text-align:left !important;\n"; + $jg_gal_elemtxt_subs = " text-align:left !important;\n"; + break; + } + + // Alignment of thumb + // Only with activated random view + switch($this->jg_ctalign) + { + case 1: + // Left aligned + $jg_gal_elemimg = " float:left;\n"; + break; + case 2: + // Right aligned + $jg_gal_elemimg = " text-align:right !important;\n"; + break; + case 3: + // Centered + $jg_gal_elemimg = " text-align:center !important;\n"; + break; + default: + // Alternating + $jg_gal_elemimg = " float:left;\n"; + break; + } + //} + + // Category view + switch($this->jg_catthumbalign) + { + case 1: + // Left aligned + if($this->jg_colnumb == 1) + { + $cat_container = " text-align:left;"; + $cat_photo = " text-align:left;"; + } + else + { + $cat_container = " float:left;"; + $cat_photo = " float:left;"; + } + $cat_txt = " text-align:left !important;"; + break; + case 2: + // Right aligned + if($this->jg_colnumb == 1) + { + $cat_container = " text-align:right !important;"; + $cat_photo = " display:block;\n text-align:right !important;"; + } + else + { + if($this->jg_imgalign == 0) + { + $cat_container = " float:right;\n text-align:right !important;\n"; + $cat_photo = " display:block;\n text-align:right !important;"; + } + else + { + $cat_container = " float:right;\n"; + $cat_photo = " text-align:right !important;"; + } + } + $cat_txt = " text-align:right !important;"; + break; + case 3: + // Centered + if($this->jg_colnumb == 1) + { + $cat_container = " text-align:center !important;"; + $cat_txt = " text-align:center !important;"; + $cat_photo = " display:block;\n text-align:center !important;"; + } + else + { + if($this->jg_imgalign == 0) + { + $cat_container = " float:left;\n text-align:center !important;\n"; + $cat_photo = " display:block;\n text-align:center !important;"; + } + else + { + $cat_container = " float:left;\n"; + $cat_photo = " text-align:center !important;"; + } + $cat_txt = " text-align:center !important;"; + } + break; + } + + // Sub-category view + // User defined alignment for subcategory thumb + if($this->jg_showsubthumbs == 1) + { + if($this->jg_colsubcat == 1) + { + $subcat_container = " text-align:left !important;\n"; + } + else + { + $subcat_container = " float:left;\n"; + } + } + // Activated random view of thumbs or no thumbs or override + //if($this->jg_showsubthumbs == 2 || $this->jg_showsubthumbs == 0 || $this->jg_showsubthumbs == 3) + //{ + switch($this->jg_subcatthumbalign) + { + case 1: + // Left aligned + if($this->jg_colsubcat == 1) + { + $subcat_container = " text-align:left !important;"; + $subcat_photo = " float:left;"; + $subcat_txt = " text-align:left !important;"; + } + else + { + $subcat_container = " float:left;"; + $subcat_photo = " float:left;"; + $subcat_txt = " text-align:left !important;"; + } + break; + case 2: + // Right aligned + if($this->jg_colsubcat == 1) + { + $subcat_container = " text-align:right !important;"; + $subcat_photo = " text-align:right !important;"; + $subcat_txt = " text-align:right !important;"; + } + else + { + $subcat_container = " float:right !important;"; + $subcat_photo = " text-align:right !important;"; + $subcat_txt = " text-align:right !important;"; + } + break; + case 3: + // Centered + if($this->jg_colsubcat == 1) + { + $subcat_container = " text-align:center !important;"; + $subcat_photo = " text-align:center !important;"; + $subcat_txt = " display:block;\n text-align:center !important;"; + } + else + { + $subcat_container = " float:left;\n text-align:center !important;"; + $subcat_photo = " text-align:center !important;\n"; + $subcat_txt = " clear:both;\n text-align:center !important;"; + } + break; + } + //} + + // Toplist view + $colwidth_top = floor (99 / $this->jg_toplistcols); + + $top_container = ''; + $top_txt = ''; + + // Only if activated + if($this->jg_showtoplist != 0 || $this->jg_favourites != 0) + { + switch($this->jg_topthumbalign) + { + case 1: + // Image left aligned + if($this->jg_toplistcols == 1) + { + $top_container = ""; + $top_photo = " width:49%;\n float:left;"; + + switch($this->jg_toptextalign) + { + // Alignment of text + case 1: + // Left aligned + $top_txt = " text-align:left !important;"; + break; + case 2: + // Right aligned + $top_txt = " text-align: right !important;"; + break; + case 3: + // Centered + $top_txt = " text-align: center !important;"; + break; + } + $top_txt .= "\n width:49%;\n float:left;"; + } + else + { + // Image and text left aligned in multi columned view + $top_container = " float:left;\n height:100%;"; + $top_photo = ""; + $top_txt = " text-align:left !important;"; + } + break; + + case 2: + // Image right aligned + if($this->jg_toplistcols == 1) + { + $top_container=""; + $top_photo=" width:49%;\n float:left;\n text-align:right !important;"; + + switch($this->jg_toptextalign) + { + // Alignment of text + case 1: + // Left aligned + $top_txt = " text-align:left !important;"; + break; + case 2: + // Right aligned + $top_txt = " text-align: right !important;"; + break; + case 3: + // Centered + $top_txt = " text-align: center !important;"; + break; + } + $top_txt .= "\n width:49%;\n float:left;"; + } + else + { + // Image and text right aligned in multi columned view + $top_container = " float:left;\n height:100%;\n text-align:right !important;"; + $top_photo = " text-align:right !important;"; + $top_txt = " text-align:right !important;"; + } + break; + + case 3: + // Image centered + if($this->jg_toplistcols == 1) + { + $top_container = ""; + $top_photo = " width:49%;\n float:left;\n text-align:center !important;"; + + switch($this->jg_toptextalign) + { + // Alignment of text + case 1: + // Left aligned + $top_txt = " text-align:left !important;"; + break; + case 2: + // Right aligned + $top_txt = " text-align:right !important;"; + break; + case 3: + // Centered + $top_txt = " text-align:center !important;"; + break; + } + $top_txt .= "\n width:49%;\n float:left;"; + } + else + { + // Image and text centered in multi columned view + $top_container = " float:left;\n height:100%;\n text-align:center !important;"; + $top_photo = " text-align:center !important"; + $top_txt = " text-align:center !important;"; + } + break; + } + } + + // Detail view + if($this->jg_minis != 0 && $this->jg_minisprop == 2 ) + { + $minidimensions = "height:".$this->jg_miniHeight."px"; + } + else + { + if($this->jg_minisprop == 1 ) + { + $minidimensions = "width:".$this->jg_miniWidth."px"; + } + else + { + $minidimensions = "width:".$this->jg_miniWidth."px;\n"; + $minidimensions .= "height:".$this->jg_miniHeight."px;\n"; + } + } + + // Search view + $colwidth_search = floor (99 / $this->jg_searchcols); + + // Only if activated + if($this->jg_search != 0) + { + switch($this->jg_searchthumbalign) + { + case 1: + // Image left aligned + if($this->jg_searchcols == 1) + { + $search_container = ""; + $search_photo = " width:49%;\n float:left;"; + + switch($this->jg_searchtextalign) + { + // Alignment of text + case 1: + // Left aligned + $search_txt = " text-align:left !important;"; + break; + case 2: + // Right aligned + $search_txt = " text-align: right !important;"; + break; + case 3: + // Centered + $search_txt = " text-align: center !important;"; + break; + } + $search_txt .= "\n width:49%;\n float:left;"; + } + else + { + $search_container = " float:left;\n height:100%;"; + $search_photo = " text-align:left !important;"; + $search_txt = " text-align:left !important;"; + } + break; + case 2: + // Image right aligned + if($this->jg_searchcols == 1) + { + $search_container = ""; + $search_photo = " width:49%;\n float:left;\n text-align:right !important;"; + + switch($this->jg_searchtextalign) + { + // Alignment of text + case 1: + // Left aligned + $search_txt = " text-align:left !important;"; + break; + case 2: + // Right aligned + $search_txt = " text-align: right !important;"; + break; + case 3: + // Centered + $search_txt = " text-align: center !important;"; + break; + } + $search_txt .= "\n width:49%;\n float:left;"; + } + else + { + $search_container = " float:left;\n height:100%;\n text-align:right !important;"; + $search_photo = " text-align: right !important;"; + $search_txt = " text-align: right !important;"; + } + break; + case 3: + // Image centered + if($this->jg_searchcols == 1) + { + $search_container = ""; + $search_photo = " width:49%;\n float:left;\n text-align:center !important;"; + + switch($this->jg_searchtextalign) + { + // Alignment of text + case 1: + // Left aligned + $search_txt = " text-align:left !important;"; + break; + case 2: + // Right aligned + $search_txt = " text-align: right !important;"; + break; + case 3: + // Centered + $search_txt = " text-align: center !important;"; + break; + } + $search_txt .= "\n width:49%;\n float:left;"; + } + else + { + $search_container = " float:left;\n height:100%;\n text-align:center !important;"; + $search_photo = " text-align: center !important;"; + $search_txt = " text-align: center !important;"; + } + break; + } + } + + // Composing and output of CSS + + $css_settings = " +/* Joomgallery CSS +CSS Styles generated by settings in the Joomgallery backend. +DO NOT EDIT - this file will be overwritten every time the config is saved. +Adjust your styles in joom_local.css instead. + +CSS Styles, die ueber die Speicherung der Konfiguration im Backend erzeugt werden. +BITTE NICHT VERAENDERN - diese Datei wird mit dem naechsten Speichern ueberschrieben. +Bitte nehmen Sie Aenderungen in der Datei joom_local.css in diesem +Verzeichnis vor. Sie koennen sie neu erstellen oder die schon vorhandene +joom_local.css.README umbenennen und anpassen +*/\n\n"; + + if(!empty($jg_common_imgalign)) + { + $css_settings .= "/* Common settings */\n"; + $css_settings .= "/* Vertical alignment of images to bottom */\n"; + $css_settings .= $jg_common_imgalign; + $css_settings .= "\n\n"; + } + + // Gallery view + $css_settings .= "/* Gallery view */\n"; + + // Container with eventually picture and categorytext + $css_settings .= ".jg_element_gal, .jg_element_gal_r {\n"; + $css_settings .= $jg_gal_container; + $css_settings .= " width:".$colwidth_gal."%;\n"; + $css_settings .= "}\n"; + + // Text + $css_settings .= ".jg_element_txt {\n"; + $css_settings .= $jg_gal_elemtxt; + $css_settings .= "}\n"; + + // Text sub-categories + $css_settings .= ".jg_element_txt_subs {\n"; + $css_settings .= $jg_gal_elemtxt_subs; + $css_settings .= " font-size: 0.9em;\n"; + $css_settings .= "}\n"; + + // Image if activated + if(($this->jg_showcatthumb == 1 || $this->jg_showcatthumb == 3 || $this->jg_showcatthumb == 2) && !empty($jg_gal_elemimg)) + { + $css_settings .= ".jg_photo_container {\n"; + $css_settings .= $jg_gal_elemimg; + $css_settings .= "}\n"; + } + + // Category view + $css_settings .= "\n/* Category view */\n"; + $css_settings .= ".jg_element_cat {\n"; + $css_settings .= " width:".$colwidth_cat."%;\n"; + $css_settings .= $cat_container."\n"; + $css_settings .= "}\n"; + $css_settings .= ".jg_catelem_cat a{\n"; + $css_settings .= " height:".$this->jg_thumbheight."px;\n"; + $css_settings .= "}\n"; + $css_settings .= ".jg_catelem_photo {\n"; + $css_settings .= $cat_photo."\n"; + $css_settings .= "}\n"; + $css_settings .= ".jg_catelem_txt {\n"; + $css_settings .= $cat_txt."\n"; + $css_settings .= "}\n"; + if($this->jg_ratingdisplaytype == 1) + { + // Rating with star graphic + $css_settings .= ".jg_starrating_cat {\n"; + $css_settings .= " width:".(int)($this->jg_maxvoting * 16)."px;\n"; + $css_settings .= " background: url(".$icon_url."star_gr.png) 0 0 repeat-x;\n"; + switch($this->jg_catthumbalign) + { + case 2: + $css_settings .= " margin-left: auto;\n"; + break; + case 3: + $css_settings .= " margin: 0 auto;\n"; + break; + default: + break; + } + $css_settings .= "}\n"; + $css_settings .= ".jg_starrating_cat div {\n"; + $css_settings .= " height:16px;\n"; + $css_settings .= " background: url(".$icon_url."star_orange.png) 0 0 repeat-x;\n"; + $css_settings .= " margin-left: 0;\n"; + $css_settings .= " margin-right: auto;\n"; + $css_settings .= "}\n"; + } + + // Sub-category view + $css_settings .= "\n/* Subcategory view */\n"; + $css_settings .= ".jg_subcatelem_cat, .jg_subcatelem_cat_r{\n"; + $css_settings .= " width:".$colwidth_subcat."%;\n"; + $css_settings .= $subcat_container."\n"; + $css_settings .= "}\n"; + $css_settings .= ".jg_subcatelem_cat a{\n"; + $css_settings .= " height:".$this->jg_thumbheight."px;\n"; + $css_settings .= "}\n"; + if(isset($subcat_photo)) + { + $css_settings .= ".jg_subcatelem_photo {\n"; + $css_settings .= $subcat_photo."\n"; + $css_settings .= "}\n"; + $css_settings .= ".jg_subcatelem_txt {\n"; + $css_settings .= $subcat_txt."\n"; + $css_settings .= "}\n"; + } + + // Detail view + $css_settings .= "\n/* Detail view */\n"; + // Motiongallery only if activated + if($this->jg_minis != 0) + { + $css_settings .= ".jg_minipic {\n"; + $css_settings .= " ".$minidimensions.";\n"; + $css_settings .= "}\n"; + + $css_settings .= "#motioncontainer {\n"; + $css_settings .= " width:".$this->jg_motionminiWidth."px; /* Set to gallery width, in px or percentage */\n"; + $css_settings .= " height:".$this->jg_motionminiHeight."px;/* Set to gallery height */\n"; + $css_settings .= "}\n"; + } + if($this->jg_ratingdisplaytype == 1) + { + // Rating with star graphic + $css_settings .= ".jg_starrating_detail {\n"; + $css_settings .= " width:".(int)($this->jg_maxvoting * 16)."px;\n"; + $css_settings .= " background: url(".$icon_url."star_gr.png) 0 0 repeat-x;\n"; + $css_settings .= "}\n"; + $css_settings .= ".jg_starrating_detail div {\n"; + $css_settings .= " height:16px;\n"; + $css_settings .= " background: url(".$icon_url."star_orange.png) 0 0 repeat-x;\n"; + $css_settings .= "}\n"; + // Rating bar + $css_settings .= ".jg_starrating_bar,\n"; + $css_settings .= ".jg_starrating_bar div:hover,\n"; + $css_settings .= ".jg_starrating_bar div:active,\n"; + $css_settings .= ".jg_starrating_bar div:focus,\n"; + $css_settings .= ".jg_starrating_bar .jg_current-rating {\n"; + $css_settings .= " background: url(".$icon_url."star_rating.png) left -1000px repeat-x;\n"; + $css_settings .= "}\n"; + $css_settings .= ".jg_starrating_bar {\n"; + $css_settings .= " position:relative;\n"; + $css_settings .= " width:".(int)($this->jg_maxvoting * 24)."px;\n"; + $css_settings .= " height:24px;\n"; + $css_settings .= " overflow:hidden;\n"; + $css_settings .= " list-style:none;\n"; + $css_settings .= " margin:0px auto !important;\n"; + $css_settings .= " padding:0 !important;\n"; + $css_settings .= " background-position:left top;\n"; + $css_settings .= "}\n"; + $css_settings .= ".jg_starrating_bar li {\n"; + $css_settings .= " display:inline;\n"; + $css_settings .= " padding:0 !important;\n"; + $css_settings .= " margin:0 !important;\n"; + $css_settings .= "}\n"; + $css_settings .= ".jg_starrating_bar div,\n"; + $css_settings .= ".jg_starrating_bar .jg_current-rating {\n"; + $css_settings .= " position:absolute;\n"; + $css_settings .= " top:0;\n"; + $css_settings .= " left:0;\n"; + $css_settings .= " text-indent:-1000em;\n"; + $css_settings .= " height:24px;\n"; + $css_settings .= " line-height:24px;\n"; + $css_settings .= " outline:none;\n"; + $css_settings .= " overflow:hidden;\n"; + $css_settings .= " border: none;\n"; + $css_settings .= "}\n"; + $css_settings .= ".jg_starrating_bar div:hover,\n"; + $css_settings .= ".jg_starrating_bar div:active,\n"; + $css_settings .= ".jg_starrating_bar div:focus {\n"; + $css_settings .= " background-position:left bottom;\n"; + $css_settings .= "}\n"; + for($i=0; $i<$this->jg_maxvoting; $i++) + { + $css_settings .= ".jg_starrating_bar div.jg_star_".($i + 1)." {\n"; + $css_settings .= " width:".(int)(100.0 / (float)$this->jg_maxvoting * (float)($i + 1))."%;\n"; + $css_settings .= " z-index:".(($this->jg_maxvoting + 1) - $i).";\n"; + $css_settings .= " cursor:pointer;\n"; + $css_settings .= " display:inline;\n"; + $css_settings .= "}\n"; + } + $css_settings .= ".jg_starrating_bar .jg_current-rating {\n"; + $css_settings .= " z-index:1;\n"; + $css_settings .= " background-position:left center;\n"; + $css_settings .= "}\n"; + } + + // Name tags only if activated + if($this->jg_nameshields != 0) + { + $css_settings .=".nameshield {\n"; + $css_settings .=" line-height:".$this->jg_nameshields_height."px;\n"; + $css_settings .="}\n"; + } + + // Toplist view (special) and favourites + if($this->jg_showtoplist != 0 || $this->jg_favourites != 0) + { + $css_settings .= "\n/* Special view - Toplists*/\n"; + $css_settings .= ".jg_topelement, .jg_favelement {\n"; + $css_settings .= " width:".$colwidth_top."%;\n"; + $css_settings .= " height:auto;\n"; + $css_settings .= $top_container."\n"; + $css_settings .= "}\n"; + + if(!empty($top_photo)) + { + $css_settings .= ".jg_topelem_photo, .jg_favelem_photo {\n"; + $css_settings .= $top_photo."\n"; + $css_settings .= "}\n"; + } + $css_settings .= ".jg_topelem_txt, .jg_favelem_txt {\n"; + $css_settings .= $top_txt."\n"; + $css_settings .= "}\n"; + } + + if($this->jg_ratingdisplaytype == 1) + { + // Rating with star graphic + $css_settings .= ".jg_starrating_fav, .jg_starrating_top {\n"; + $css_settings .= " width:".(int)($this->jg_maxvoting * 16)."px;\n"; + $css_settings .= " background: url(".$icon_url."star_gr.png) 0 0 repeat-x;\n"; + $setting = (($this->jg_toplistcols == 1) ? $this->jg_toptextalign : $this->jg_topthumbalign); + switch($setting) + { + case 2: + $css_settings .= " margin-left: auto;\n"; + break; + case 3: + $css_settings .= " margin: 0 auto;\n"; + break; + default: + break; + } + $css_settings .= "}\n"; + $css_settings .= ".jg_starrating_fav div, .jg_starrating_top div {\n"; + $css_settings .= " height:16px;\n"; + $css_settings .= " background: url(".$icon_url."star_orange.png) 0 0 repeat-x;\n"; + $css_settings .= " margin-left: 0;\n"; + $css_settings .= " margin-right: auto;\n"; + $css_settings .= "}\n"; + } + + // Search view + if($this->jg_search != 0) + { + $css_settings .= "\n/* Search view*/\n"; + $css_settings .= ".jg_searchelement {\n"; + $css_settings .= " width:".$colwidth_search."%;\n"; + $css_settings .= " height:auto;\n"; + if(!empty($search_container)) + { + $css_settings .= $search_container."\n"; + } + $css_settings .= "}\n"; + + if(!empty($search_photo)) + { + $css_settings .= ".jg_searchelem_photo {\n"; + $css_settings .= $search_photo."\n"; + $css_settings .= "}\n"; + } + + $css_settings .= ".jg_searchelem_txt {\n"; + $css_settings .= $search_txt."\n"; + $css_settings .= "}\n"; + + if($this->jg_ratingdisplaytype == 1) + { + // Rating with star graphic + $css_settings .= ".jg_starrating_search {\n"; + $css_settings .= " width:".(int)($this->jg_maxvoting * 16)."px;\n"; + $css_settings .= " background: url(".$icon_url."star_gr.png) 0 0 repeat-x;\n"; + $setting = (($this->jg_searchcols == 1) ? $this->jg_searchtextalign : $this->jg_searchthumbalign); + switch($setting) + { + case 2: + $css_settings .= " margin-left: auto;\n"; + break; + case 3: + $css_settings .= " margin: 0 auto;\n"; + break; + default: + break; + } + $css_settings .= "}\n"; + $css_settings .= ".jg_starrating_search div {\n"; + $css_settings .= " height:16px;\n"; + $css_settings .= " background: url(".$icon_url."star_orange.png) 0 0 repeat-x;\n"; + $css_settings .= " margin-left: 0;\n"; + $css_settings .= " margin-right: auto;\n"; + $css_settings .= "}\n"; + } + } + + // Save the file + jimport('joomla.filesystem.file'); + $css_settings_file = JPATH_ROOT.'/media/joomgallery/css/'.$this->getStyleSheetName($this->id); + if(!JFile::write($css_settings_file, $css_settings)) + { + return false; + } + + return true; + } + + /** + * Deletes a specific configuration row and corresponding CSS file + * + * @param int $id The Id of the row to delete + * @return boolean True on success, false otherwise + * @since 2.0 + */ + public function delete($id) + { + if($id == 1) + { + $this->setError(JText::_('COM_JOOMGALLERY_CONFIGS_DEFAULT_ROW_NOT_DELETABLE')); + + return false; + } + + $config = JTable::getInstance('joomgalleryconfig', 'Table'); + + if(!$config->delete($id)) + { + $this->setError($config->getError()); + + return false; + } + + jimport('joomla.filesystem.file'); + $css_settings_file = JPATH_ROOT.'/media/joomgallery/css/'.$this->getStyleSheetName($id); + if(!JFile::delete($css_settings_file)) + { + return false; + } + + return true; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/helpers/ambit.php b/deployed/joomgallery/administrator/components/com_joomgallery/helpers/ambit.php new file mode 100644 index 00000000..95df2d44 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/helpers/ambit.php @@ -0,0 +1,504 @@ +icon_url = JURI::root().'media/joomgallery/images/'; + $this->css_url = JURI::root().'media/joomgallery/css/'; + $this->js_url = JURI::root().'media/joomgallery/js/'; + + $this->_external['thumb'] = false; + $this->thumb_url = JURI::root().$config->get('jg_paththumbs'); + $this->thumb_path = JPath::clean(JPATH_ROOT.'/'.$config->get('jg_paththumbs')); + if(!JFolder::exists($this->thumb_path)) + { + $this->_external['thumb'] = true; + $this->thumb_url = ''; + $this->thumb_path = JPath::clean($config->get('jg_paththumbs')); + } + + $this->_external['img'] = false; + $this->img_url = JURI::root().$config->get('jg_pathimages'); + $this->img_path = JPath::clean(JPATH_ROOT.'/'.$config->get('jg_pathimages')); + if(!JFolder::exists($this->img_path)) + { + $this->_external['img'] = true; + $this->img_url = ''; + $this->img_path = JPath::clean($config->get('jg_pathimages')); + } + + $this->_external['orig'] = false; + $this->orig_url = JURI::root().$config->get('jg_pathoriginalimages'); + $this->orig_path = JPath::clean(JPATH_ROOT.'/'.$config->get('jg_pathoriginalimages')); + if(!JFolder::exists($this->orig_path)) + { + $this->_external['orig'] = true; + $this->orig_url = ''; + $this->orig_path = JPath::clean($config->get('jg_pathoriginalimages')); + } + + $this->temp_path = JPath::clean(JPATH_ROOT.'/'.$config->get('jg_pathtemp')); + if(!JFolder::exists($this->temp_path)) + { + $this->temp_path = JPath::clean($config->get('jg_pathtemp')); + } + $this->ftp_path = JPath::clean(JPATH_ROOT.'/'.$config->get('jg_pathftpupload')); + if(!JFolder::exists($this->ftp_path)) + { + $this->ftp_path = JPath::clean($config->get('jg_pathftpupload')); + } + $this->wtm_path = JPath::clean(JPATH_ROOT.'/'.$config->get('jg_wmpath')); + if(!JFolder::exists($this->wtm_path)) + { + $this->wtm_path = JPath::clean($config->get('jg_wmpath')); + } + + if(!$this->version = $mainframe->getUserState('joom.version.string')) + { + $this->version = JoomExtensions::getGalleryVersion(); + $mainframe->setUserState('joom.version.string', $this->version); + } + } + + /** + * Returns a reference to the global Ambit object, only creating it if it + * doesn't already exist. + * + * This method must be invoked as: + *
      $ambit = JoomAmbit::getInstance();
    + * + * @return JoomAmbit The Ambit object. + * @since 1.5.5 + */ + public static function getInstance() + { + static $instance; + + if(!isset($instance)) + { + $instance = new JoomAmbit(); + } + + return $instance; + } + + /** + * Returns the URL to an icon + * + * @param string $icon The filename of the icon + * @return string The URL to the icon + * @since 1.5.5 + */ + public function getIcon($icon) + { + return $this->get('icon_url').$icon; + } + + /** + * Returns the URL to a style sheet + * + * @param string $stylesheet The filename of the style sheet + * @return string The URL to the style sheet + * @since 1.5.5 + */ + public function getStyleSheet($stylesheet) + { + return $this->get('css_url').$stylesheet; + } + + /** + * Returns the URL to a script file + * + * @param string $script The filename of the script file + * @return string The URL to the script file + * @since 1.5.5 + */ + public function getScript($script) + { + return $this->get('js_url').$script; + } + + /** + * Returns the URL for a redirect + * + * @param string $controller The controller used in the redirect url + * if it is null, we will use the same + * controller as in the current request, + * if it is an empty string, we will redirect + * to the control panel of the gallery + * @param int $id The ID of a category or image to redirect to + * if the task was 'apply' + * @param string $key The parameter name to use in the URL for the ID + * @return string The redirect URL + * @since 1.5.5 + */ + public function getRedirectUrl($controller = null, $id = null, $key = 'cid') + { + $url = 'index.php?option='._JOOM_OPTION; + + if(is_null($controller)) + { + $url .= '&controller='.JRequest::getCmd('controller'); + if(!is_null($id) && JRequest::getCmd('task') == 'apply') + { + $url .= '&task=edit&'.$key.'='.$id; + } + } + else + { + if($controller) + { + $url .= '&controller='.$controller; + } + } + + return $url; + } + + /** + * Returns the URL or the path to an image + * + * @param string $type The type of the URL or path + * @param string/object/int $img Filename, database object or ID of the image + * @param int $catid The ID of the category in which the image is stored + * @return string The URL or the path to the image + * @since 1.5.5 + */ + public function getImg($type, $img, $id = 0, $catid = 0) + { + $types = array('thumb_path', 'thumb_url', 'img_path', 'img_url', 'orig_path', 'orig_url'); + if(!in_array($type, $types)) + { + JError::raiseError(500, JText::sprintf('Wrong image type: %s', $type)); + } + + if(!is_object($img)) + { + if(is_numeric($img)) + { + $img = $this->getImgObject($img); + } + else + { + if(!is_null($id)) + { + $img = $this->getImgObject($id); + } + } + } + + if(is_object($img)) + { + $id = $img->id; + $catid = $img->catid; + if($type == 'thumb_path' || $type == 'thumb_url') + { + $img = $img->imgthumbname; + } + else + { + $img = $img->imgfilename; + } + } + + // Check whether the image shall be output through the PHP script or with its real path + if( strpos($type, 'url') + && + ( $this->_external[str_replace('_url','', $type)] + #|| $this->_config->get('jg_watermark') + || strpos($type, 'img') !== false + || strpos($type, 'orig') !== false + ) + ) + { + $type = str_replace('_url','', $type); + return JRoute::_('index.php?option='._JOOM_OPTION.'&controller=images&view=image&format=raw&type='.$type.'&cid='.$id); + } + + $catpath = JoomHelper::getCatPath($catid); + + // Create the complete path + $img = $this->$type . $catpath . $img; + + if(strpos($type, 'path')) + { + $img = JPath::clean($img); + } + + return $img; + } + + /** + * Returns the database row of a specific image + * + * @param int $id The ID of the image to load + * @return object The database row of the image + */ + public function getImgObject($id) + { + static $images = array(); + static $row; + + if(!isset($images[$id])) + { + if(!isset($row)) + { + $row = JTable::getInstance('joomgalleryimages', 'Table'); + } + + if(!$row->load($id)) + { + JError::raiseError(500, JText::sprintf('Image with ID %d not found', $id)); + } + + $properties = $row->getProperties(); + $images[$id] = new stdClass(); + foreach($properties as $key => $value) + { + $images[$id]->$key = $value; + } + } + + return $images[$id]; + } + + /** + * Returns the category structure of the gallery + * + * @param boolean True, if a structure with all categories should be constructed. + * @return array An array of categories/sub-categories + * @since 1.5.5 + */ + public function getCategoryStructure($all = false) + { + // Check if already read from database + if( (is_null($this->_categorystructure) && !$all) + || (is_null($this->_allcategorystructure) && $all) + ) + { + // Creation of array + $database = JFactory::getDBO(); + $user = JFactory::getUser(); + + // Read all categories from database + $query = $database->getQuery(true) + ->select('c.cid, c.parent_id, c.name, c.access, c.published, c.hidden, c.owner') + ->from(_JOOM_TABLE_CATEGORIES.' AS c') + ->where('lft > 0') + ->order('c.lft'); + + if(!$user->authorise('core.admin') && !$all) + { + $query->where('c.access IN ('.implode(',', $user->getAuthorisedViewLevels()).')'); + } + + $database->setQuery($query); + $categories = $database->loadObjectList('cid'); + + // Get picture count and hits count + $query->clear() + ->select('catid, COUNT(id) as piccount, SUM(hits) as hitcount') + ->from(_JOOM_TABLE_IMAGES) + ->group('catid'); + + if(!$user->authorise('core.admin') && !$all) + { + $query->where('access IN ('.implode(',', $user->getAuthorisedViewLevels()).')'); + } + + $database->setQuery($query); + $catcounts = $database->loadObjectList('catid'); + + // Merge the arrays + foreach($categories as $key => $category) + { + if($category->parent_id != 1 && !isset($categories[$category->parent_id])) + { + unset($categories[$key]); + continue; + } + + // Cast to int where needful + $categories[$key]->cid = (int) $key; + $categories[$key]->parent_id = (int) $categories[$key]->parent_id; + + if(isset($catcounts[$key])) + { + $categories[$key]->piccount = (int) $catcounts[$key]->piccount; + $categories[$key]->hitcount = (int) $catcounts[$key]->hitcount; + } + else + { + $categories[$key]->piccount = 0; + $categories[$key]->hitcount = 0; + } + } + + if($all) + { + $this->_allcategorystructure = $categories; + } + else + { + $this->_categorystructure = $categories; + } + } + + if(!$all) + { + return $this->_categorystructure; + } + else + { + return $this->_allcategorystructure; + } + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/helpers/config.php b/deployed/joomgallery/administrator/components/com_joomgallery/helpers/config.php new file mode 100644 index 00000000..3d6e9fcd --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/helpers/config.php @@ -0,0 +1,497 @@ +get('extended_config')) + { + $this->_extended = true; + } + + if(!is_null($id) || !$this->_extended) + { + if(!$this->_extended) + { + // If extended configuration manager is + // disabled we use the default config row + $id = 1; + } + + $id = intval($id); + + $this->_id = $id; + + $config = JTable::getInstance('joomgalleryconfig', 'Table'); + $config->load($this->_id); + + // Get config values + $properties = $config->getProperties(); + } + else + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('*') + ->from(_JOOM_TABLE_CONFIG) + ->where('group_id IN ('.implode(',', JFactory::getUser()->getAuthorisedGroups()).')') + ->order('ordering DESC'); + $db->setQuery($query, 0, 1); + if(!$properties = $db->loadAssoc()) + { + JError::raiseError(500, JText::_('Error loading config data')); + } + + $this->_id = $properties['id']; + } + + // Populate configuration values + unset($properties['id']); + unset($properties['group_id']); + unset($properties['ordering']); + foreach($properties as $key => $value) + { + $this->$key = $value; + } + } + + /** + * Returns a reference to the global Config object, only creating it if it + * doesn't already exist. + * + * This method must be invoked as: + *
      $config = JoomAmbit::getInstance();
    + * + * @param mixed The ID of the requested configuration row or string 'admin' + if additional handling for storing the config is necessary + * @return JoomConfig The Config object. + * @since 1.5.5 + */ + public static function getInstance($id = null) + { + static $instances; + + if(!isset($instances)) + { + $instances = array(); + } + + if(empty($instances[$id])) + { + if($id == 'admin') + { + require_once JPATH_ADMINISTRATOR.'/components/'._JOOM_OPTION.'/helpers/adminconfig.php'; + $config = new JoomAdminConfig(); + } + else + { + $config = new JoomConfig($id); + } + + $instances[$id] = $config; + } + + return $instances[$id]; + } + + /** + * Returns true if the extended configuration manager is enabled + * + * @return boolean True if extended configuration manager is enabled, false otherwise + * @since 2.0 + */ + public function isExtended() + { + return $this->_extended; + } + + /** + * Returns the CSS file name for the current config row or a specific one + * + * @param int ID of a specific row for which the CSS file name should be returned, 0 if the current one should be used + * @return string The CSS file name of the current config row + * @since 2.0 + */ + public function getStyleSheetName($id = 0) + { + if($id) + { + if($id == 1) + { + $id = ''; + } + + return 'joom_settings'.$id.'.css'; + } + + if($this->_id == 1) + { + return 'joom_settings.css'; + } + + return 'joom_settings'.$this->_id.'.css'; + } + + /** + * Returns a string containing a valid image sorting ORDER BY clause for a given index or an + * array containing all of them. + * + * @param mixed $index + * @return mixed A string containing a valid image sorting ORDER BY clause or an array + * containing all of them. + * @since 3.3 + */ + public static function getValidImageSortingOrderByClauses($index = false) + { + return $index !== false ? self::$_validImageSortingOrderByClauses[$index] : self::$_validImageSortingOrderByClauses; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/helpers/extensions.php b/deployed/joomgallery/administrator/components/com_joomgallery/helpers/extensions.php new file mode 100644 index 00000000..8349b4b8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/helpers/extensions.php @@ -0,0 +1,342 @@ +getTag(), 'de-') === false) + { + $subdomain = 'en.'; + } + + $site = 'http://www.'.$subdomain.'joomgallery.net'; + $site2 = 'http://'.$subdomain.'joomgallery.net'; + $rssurl = $site.'/components/com_newversion/rss/extensions3.rss'; + + // Get RSS parsed object + $rssDoc = false; + try + { + $feed = new JFeedFactory; + $rssDoc = $feed->getFeed($rssurl); + } + catch (InvalidArgumentException $e) + { + } + catch (RunTimeException $e) + { + } + + $extensions = array(); + if($rssDoc != false) + { + for($i = 0; isset($rssDoc[$i]); $i++) + { + $item = $rssDoc[$i]; + $name = $item->title; + + // The data type is delivered as the name of the first category + $categories = $item->categories; + $type = key($categories); + switch($type) + { + case 'general': + $description = $item->content; + $link = $item->uri; + if(!is_null($description) && $description != '') + { + $extensions[$name]['description'] = $description; + } + if(!is_null($link) && $link != $site && $link != $site2) + { + $extensions[$name]['downloadlink'] = $link; + } + break; + case 'version': + $version = $item->content; + $link = $item->uri; + if(!is_null($version) && $version != '') + { + $extensions[$name]['version'] = $version; + } + if(!is_null($link) && $link != $site && $link != $site2) + { + $extensions[$name]['releaselink'] = $link; + } + break; + case 'autoupdate': + $xml = $item->content; + $link = $item->uri; + if(!is_null($xml) && $xml != '') + { + $extensions[$name]['xml'] = $xml; + } + if(!is_null($link) && $link != $site && $link != $site2) + { + $extensions[$name]['updatelink'] = $link; + } + break; + default: + break; + } + } + + // Sort the extensions in alphabetical order + ksort($extensions); + } + + return $extensions; + } + + /** + * Returns all installed JoomGallery extensions and JoomGallery itself + * with additional information provided by getAvailableExtensions + * + * @param array $extensions Extensions provided by getAvailableExtensions + * @return array Two-dimensional array with extension information + * @since 1.5.0 + */ + public static function getInstalledExtensions($extensions = null) + { + static $installed_extensions; + + if(isset($installed_extensions)) + { + return $installed_extensions; + } + + if(is_null($extensions)) + { + $extensions = JoomExtensions::getAvailableExtensions(); + } + + $installed_extensions = array(); + foreach($extensions as $name => $extension) + { + if(!isset($extension['xml'])) + { + continue; + } + $xml_file = JPath::clean(JPATH_ROOT.'/'.$extension['xml']); + if(file_exists($xml_file)) + { + $installed_extensions[$name] = $extension; + + $xml = simplexml_load_file($xml_file); + + $installed_version = (string) $xml->version; + $installed_extensions[$name]['installed_version'] = $installed_version; + } + } + + return $installed_extensions; + } + + /** + * Compares all installed extension versions with the current ones + * and returns all dated JoomGallery extensions and JoomGallery itself + * with additional information provided by getAvailableExtensions + * + * @param array $extensions Installed extensions provided by getInstalledExtensions + * @return array Two-dimensional array with extension information + * @since 1.5.0 + */ + public static function checkUpdate($extensions = null) + { + static $dated_extensions; + + if(isset($dated_extensions)) + { + return $dated_extensions; + } + + if(is_null($extensions)) + { + $extensions = JoomExtensions::getInstalledExtensions(); + } + + $dated_extensions = array(); + foreach($extensions as $name => $extension) + { + if(version_compare($extension['version'], $extension['installed_version'], '>')) + { + $dated_extensions[$name] = $extension; + } + } + + return $dated_extensions; + } + + /** + * Returns the currently installed version of JoomGallery + * + * @return string Version + * @since 1.5.0 + */ + public static function getGalleryVersion() + { + static $version; + + if(!isset($version)) + { + $config = JoomConfig::getInstance(); + + $version_from_xml = true; + + // Do not read RSS file if update check is disabled + if($config->get('jg_checkupdate')) + { + $version_from_xml = false; + + $mainframe = JFactory::getApplication('administrator'); + if(!$version = $mainframe->getUserState('joom.version.string')) + { + $extensions = JoomExtensions::getInstalledExtensions(); + + if(isset($extensions['JoomGallery']['installed_version'])) + { + $version = $extensions['JoomGallery']['installed_version']; + } + else + { + $version_from_xml = true; + } + + $mainframe->setUserState('joom.version.string', $version); + } + } + + if($version_from_xml) + { + $xml_file = JPATH_ADMINISTRATOR.'/components/com_joomgallery/joomgallery.xml'; + if(file_exists($xml_file)) + { + $xml = simplexml_load_file($xml_file); + + if(!isset($xml->version)) + { + $version = 'not found'; + } + else + { + $version = (string) $xml->version; + } + } + } + } + + return $version; + } + + /** + * Fetches an update zip file from JoomGallery server and extracts it + * + * @param string $url The URL to the zip to fetch and extract + * @return void + * @since 1.5.0 + */ + public static function autoUpdate($url) + { + $mainframe = JFactory::getApplication(); + + if(!$url || !extension_loaded('curl')) + { + $mainframe->redirect('index.php?option='._JOOM_OPTION, JText::_('COM_JOOMGALLERY_ADMENU_MSG_ERROR_FETCHING_ZIP'), 'error'); + } + + $ambit = JoomAmbit::getInstance(); + + // Create curl resource + $ch = curl_init(strtolower($url)); + + // Some settings for curl + curl_setopt($ch, CURLOPT_HTTPHEADER, array('User-Agent: JoomGallery v3')); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + + // Create the zip file + jimport('joomla.filesystem.file'); + $config = JoomConfig::getInstance(); + $output = curl_exec($ch); + JFile::write($ambit->get('temp_path').'update.zip', $output); + + // Close curl resource to free up system resources + curl_close($ch); + + // Delete files and folders from previous updates + $folder = $ambit->get('temp_path').'update'; + if(JFolder::exists($folder)) + { + JFolder::delete($folder); + } + + // Extract the zip file + jimport('joomla.filesystem.archive'); + if(!JArchive::extract($ambit->get('temp_path').'update.zip', $folder)) + { + $mainframe->redirect('index.php?option='._JOOM_OPTION, JText::_('Error extracting the zip'), 'error'); + } + + // Copy an index.html into the created folder if there isn't already one + if(!JFile::exists($folder.'/index.html')) + { + $src = JPATH_ROOT.'/media/joomgallery/index.html'; + $dest = $folder.'/index.html'; + + JFile::copy($src, $dest); + } + + $mainframe->enqueueMessage(JText::_('COM_JOOMGALLERY_ADMENU_REDIRECT_NOTE'), 'notice'); + + // Let's redirect to do the rest +?> +
    + + + + +
    + + server misconfiguration + $orig = strtolower($orig); + } + } + else + { + // TODO no mbstring loaded, appropriate server for Joomla? + $orig = strtolower($orig); + } + + // Replace special chars + $filenamesearch = array(); + $filenamereplace = array(); + + $filenamereplacearr = $config->get('jg_filenamereplace'); + $items = explode(',', $filenamereplacearr); + if($items != FALSE) + { + // Contains pairs of | + foreach($items as $item) + { + if(!empty($item)) + { + $workarray = explode('|', trim($item)); + if( $workarray != FALSE + && isset($workarray[0]) && !empty($workarray[0]) + && isset($workarray[1]) && !empty($workarray[1]) + ) + { + array_push($filenamesearch, preg_quote($workarray[0])); + array_push($filenamereplace, preg_quote($workarray[1])); + } + } + } + } + + // Replace whitespace with underscore + array_push($filenamesearch, '\s'); + array_push($filenamereplace, '_'); + // Replace slash with underscore + array_push($filenamesearch, '/'); + array_push($filenamereplace, '_'); + // Replace backslash with underscore + array_push($filenamesearch, '\\\\'); + array_push($filenamereplace, '_'); + // Replace other stuff + array_push($filenamesearch, '[^a-z_0-9-]'); + array_push($filenamereplace, ''); + + // Checks for different array-length + $lengthsearch = count($filenamesearch); + $lengthreplace = count($filenamereplace); + if($lengthsearch > $lengthreplace) + { + while($lengthsearch > $lengthreplace) + { + array_push($filenamereplace, ''); + $lengthreplace = $lengthreplace + 1; + } + } + else + { + if($lengthreplace > $lengthsearch) + { + while($lengthreplace > $lengthsearch) + { + array_push($filenamesearch, ''); + $lengthsearch = $lengthsearch + 1; + } + } + } + + // Checks for extension + $extensions = array('.jpeg','.jpg','.jpe','.gif','.png'); + $extension = false; + for($i = 0; $i < count($extensions); $i++) + { + $extensiontrue = substr_count($orig, $extensions[$i]); + if($extensiontrue != 0 ) + { + $extension = true; + // If extension found, break + break; + } + } + // Replace extension if present + if($extension) + { + $fileextension = JFile::getExt($orig); + $fileextensionlength = strlen($fileextension); + $filenamelength = strlen($orig); + $filename = substr($orig, -$filenamelength, -$fileextensionlength - 1); + } + else + { + // No extension found (Batchupload) + $filename = $orig; + } + for($i = 0; $i < $lengthreplace; $i++) + { + $searchstring = '!'.$filenamesearch[$i].'+!i'; + $filename = preg_replace($searchstring, $filenamereplace[$i], $filename); + } + if($extension && !$replace_extension) + { + // Return filename with extension for regular upload + return $filename.'.'.$fileextension; + } + else + { + // Return filename without extension for batchupload + return $filename; + } + } + + /** + * Check filename if it's valid for the filesystem + * @param string $nameb filename before any processing + * @param string $namea filename after processing in e.g. fixFilename + * @param boolean $checkspecial True if the filename shall be checked for + * special characters only + * @return boolean True if the filename is valid, false otherwise + * @since 2.0 + */ + public static function checkValidFilename($nameb, $namea = '', $checkspecial = false) + { + // TODO delete this function and the call of them? + return true; + + // Check only for special characters + if($checkspecial) + { + $pattern = '/[^0-9A-Za-z -_]/'; + $check = preg_match($pattern, $nameb); + if($check == 0) + { + // No special characters found + return true; + } + else + { + return false; + } + } + // Remove extension from names + $nameb = JFile::stripExt($nameb); + $namea = JFile::stripExt($namea); + + // Check the old filename for containing only underscores + if(strlen($nameb) - substr_count($nameb, '_') == 0) + { + $nameb_onlyus = true; + } + else + { + $nameb_onlyus = false; + } + if( empty($namea) + || ( !$nameb_onlyus + && strlen($namea) == substr_count($nameb, '_') + ) + ) + { + return false; + } + else + { + return true; + } + } + + + /** + * Changes the permissions of a directory (or file) + * either by the FTP-Layer if enabled + * or by JPath::setPermissions (chmod()). + * + * Not sure but probable: J! 1.6 will use + * FTP-Layer automatically in setPermissions + * so JoomFile::chmod will become unnecessary. + * + * @param string $path Directory or file for which the permissions will be changed + * @param string $mode Permissions which will be applied to $path + * @param boolean $is_dir True if the given path is a directory, false if it is a file + * @return boolean True on success, false otherwise + * @since 1.5.0 + */ + public static function chmod($path, $mode, $is_dir = false) + { + static $ftpOptions; + + if(!isset($ftpOptions)) + { + // Initialize variables + jimport('joomla.client.helper'); + $ftpOptions = JClientHelper::getCredentials('ftp'); + } + + if($ftpOptions['enabled'] == 1) + { + // Connect the FTP client + jimport('joomla.client.ftp'); + $ftp = JFTP::getInstance($ftpOptions['host'], $ftpOptions['port'], array(), $ftpOptions['user'], $ftpOptions['pass']); + // Translate path to FTP path + $path = JPath::clean(str_replace(JPATH_ROOT, $ftpOptions['root'], $path), '/'); + + return $ftp->chmod($path, $mode); + } + else + { + if($is_dir) + { + return JPath::setPermissions(JPath::clean($path), null, $mode); + } + + return JPath::setPermissions(JPath::clean($path), $mode, null); + } + } + + /** + * Resize image with functions from gd/gd2/imagemagick + * + * Cropping function adapted from + * 'Resize Image with Different Aspect Ratio' + * Author: Nash + * Website: http://nashruddin.com/Resize_Image_to_Different_Aspect_Ratio_on_the_fly + * + * @param &string $debugoutput debug information + * @param string $src_file Path to source file + * @param string $dest_file Path to destination file + * @param int $useforresizedirection Thumbnails only: + * Resize to width/height ratio or free setting + * @param int $new_width Width to resize + * @param int $thumbheight Height to resize + * @param int $method 1=gd1, 2=gd2, 3=im + * @param int $dest_qual $config->jg_thumbquality/jg_picturequality + * @param boolean $max_width true=resize to maxwidth + * @param int $cropposition $config->jg_cropposition + * @return boolean True on success, false otherwise + * @since 1.0.0 + */ + public static function resizeImage(&$debugoutput, $src_file, $dest_file, $useforresizedirection, + $new_width, $thumbheight, $method, $dest_qual, $max_width = false, $cropposition) + { + $config = JoomConfig::getInstance(); + + // Ensure that the pathes are valid and clean + $src_file = JPath::clean($src_file); + $dest_file = JPath::clean($dest_file); + + // Doing resize instead of thumbnail, copy original and remove it. + $imginfo = getimagesize($src_file); + + if(!$imginfo) + { + $debugoutput .= JText::_('COM_JOOMGALLERY_UPLOAD_FILE_NOT_FOUND').'
    '; + + return false; + } + + // GD can only handle JPG & PNG images + if( $imginfo[2] != IMAGETYPE_JPEG + && $imginfo[2] != IMAGETYPE_PNG + && $imginfo[2] != IMAGETYPE_GIF + && ($method == 'gd1' || $method == 'gd2') + ) + { + $debugoutput .= JText::_('COM_JOOMGALLERY_UPLOAD_GD_ONLY_JPG_PNG').'
    '; + + return false; + } + + $imagetype = array(1 => 'GIF', 2 => 'JPG', 3 => 'PNG', 4 => 'SWF', 5 => 'PSD', + 6 => 'BMP', 7 => 'TIFF', 8 => 'TIFF', 9 => 'JPC', 10 => 'JP2', + 11 => 'JPX', 12 => 'JB2', 13 => 'SWC', 14 => 'IFF'); + + $imginfo[2] = $imagetype[$imginfo[2]]; + + // Height/width + $srcWidth = $imginfo[0]; + $srcHeight = $imginfo[1]; + + if( ($max_width && $srcWidth <= $new_width && $srcHeight <= $new_width) + || (!$max_width && $srcWidth <= $new_width && $srcHeight <= $thumbheight) + ) + { + // If source image is already of the same size or smaller than the image + // which shall be created only copy the source image to destination + $debugoutput .= JText::_('COM_JOOMGALLERY_UPLOAD_RESIZE_NOT_NECESSARY').'
    '; + if(!JFile::copy($src_file, $dest_file)) + { + $debugoutput .= JText::sprintf('COM_JOOMGALLERY_UPLOAD_OUTPUT_PROBLEM_COPYING', $dest_file).' '.JText::_('COM_JOOMGALLERY_COMMON_CHECK_PERMISSIONS').'
    '; + + return false; + } + + return true; + } + + // For free resizing and cropping the center + $offsetx = null; + $offsety = null; + if($max_width) + { + $debugoutput .= JText::_('COM_JOOMGALLERY_UPLOAD_RESIZE_TO_MAX').'
    '; + + if($new_width <= 0) + { + $debugoutput .= JText::_('COM_JOOMGALLERY_UPLOAD_ERROR_NO_VALID_WIDTH_OR_HEIGHT').'
    '; + + return false; + } + + $ratio = max($srcHeight,$srcWidth) / $new_width ; + } + else + { + // Resizing to thumbnail + $debugoutput .= JText::_('COM_JOOMGALLERY_UPLOAD_CREATE_THUMBNAIL_FROM').' '.$imginfo[2].', '.$imginfo[0].' x '.$imginfo[1].'...
    '; + + if($new_width <= 0 || $thumbheight <= 0) + { + $debugoutput .= JText::_('COM_JOOMGALLERY_UPLOAD_ERROR_NO_VALID_WIDTH_OR_HEIGHT').'
    '; + + return false; + } + + switch($useforresizedirection) + { + // Convert to height ratio + case 0: + $ratio = ($srcHeight / $thumbheight); + $testwidth = ($srcWidth / $ratio); + // If new width exceeds setted max. width + if($testwidth > $new_width) + { + $ratio = ($srcWidth / $new_width); + } + break; + // Convert to width ratio + case 1: + $ratio = ($srcWidth / $new_width); + $testheight = ($srcHeight/$ratio); + // If new height exceeds the setted max. height + if($testheight>$thumbheight) + { + $ratio = ($srcHeight/$thumbheight); + } + break; + // Free resizing and cropping the center + case 2: + if($srcWidth < $new_width) + { + $new_width = $srcWidth; + } + if($srcHeight < $thumbheight) + { + $thumbheight = $srcHeight; + } + // Expand the thumbnail's aspect ratio + // to fit the width/height of the image + $ratiowidth = $srcWidth / $new_width; + $ratioheight = $srcHeight / $thumbheight; + if ($ratiowidth < $ratioheight) + { + $ratio = $ratiowidth; + } + else + { + $ratio = $ratioheight; + } + // Calculate the offsets for cropping the source image according + // to thumbposition + switch($cropposition) + { + // Left upper corner + case 0: + $offsetx = 0; + $offsety = 0; + break; + // Right upper corner + case 1: + $offsetx = floor(($srcWidth - ($new_width * $ratio))); + $offsety = 0; + break; + // Left lower corner + case 3: + $offsetx = 0; + $offsety = floor(($srcHeight - ($thumbheight * $ratio))); + break; + // Right lower corner + case 4: + $offsetx = floor(($srcWidth - ($new_width * $ratio))); + $offsety = floor(($srcHeight - ($thumbheight * $ratio))); + break; + // Default center + default: + $offsetx = floor(($srcWidth - ($new_width * $ratio)) * 0.5); + $offsety = floor(($srcHeight - ($thumbheight * $ratio)) * 0.5); + break; + } + } + } + + if(is_null($offsetx) && is_null($offsety)) + { + $ratio = max($ratio, 1.0); + + $destWidth = (int)($srcWidth / $ratio); + $destHeight = (int)($srcHeight / $ratio); + } + else + { + $destWidth = $new_width; + $destHeight = $thumbheight; + $srcWidth = (int)($destWidth * $ratio); + $srcHeight = (int)($destHeight * $ratio); + } + + // Method for creation of the resized image + switch($method) + { + case 'gd1': + if(!function_exists('imagecreatefromjpeg')) + { + $debugoutput.=JText::_('COM_JOOMGALLERY_UPLOAD_GD_LIBARY_NOT_INSTALLED'); + return false; + } + if($imginfo[2] == 'JPG') + { + $src_img = imagecreatefromjpeg($src_file); + } + else + { + if ($imginfo[2] == 'PNG') + { + $src_img = imagecreatefrompng($src_file); + } + else + { + $src_img = imagecreatefromgif($src_file); + } + } + if(!$src_img) + { + return false; + } + $dst_img = imagecreate($destWidth, $destHeight); + if (!is_null($offsetx) && !is_null($offsety)) + { + imagecopyresized( $dst_img, $src_img, 0, 0, $offsetx, $offsety, + $destWidth, (int)$destHeight, $srcWidth, $srcHeight); + } + else + { + imagecopyresized( $dst_img, $src_img, 0, 0, 0, 0, $destWidth, + (int)$destHeight, $srcWidth, $srcHeight); + } + if(!@imagejpeg($dst_img, $dest_file, $dest_qual)) + { + // Workaround for servers with wwwrun problem + $dir = dirname($dest_file); + JoomFile::chmod($dir, '0777', true); + imagejpeg($dst_img, $dest_file, $dest_qual); + JoomFile::chmod($dir, '0755', true); + } + imagedestroy($src_img); + imagedestroy($dst_img); + break; + case 'gd2': + if(!function_exists('imagecreatefromjpeg')) + { + $debugoutput.=JText::_('COM_JOOMGALLERY_UPLOAD_GD_LIBARY_NOT_INSTALLED'); + return false; + } + if(!function_exists('imagecreatetruecolor')) + { + $debugoutput.=JText::_('COM_JOOMGALLERY_UPLOAD_GD_NO_TRUECOLOR'); + return false; + } + if($imginfo[2] == 'JPG') + { + $src_img = imagecreatefromjpeg($src_file); + } + else + { + if($imginfo[2] == 'PNG') + { + $src_img = imagecreatefrompng($src_file); + } + else + { + $src_img = imagecreatefromgif($src_file); + } + } + + if(!$src_img) + { + return false; + } + $dst_img = imagecreatetruecolor($destWidth, $destHeight); + + if($config->jg_fastgd2thumbcreation == 0) + { + if(!is_null($offsetx) && !is_null($offsety)) + { + imagecopyresampled( $dst_img, $src_img, 0, 0, $offsetx, $offsety, + $destWidth, (int)$destHeight, $srcWidth, $srcHeight); + } + else + { + imagecopyresampled( $dst_img, $src_img, 0, 0, 0, 0, $destWidth, + (int)$destHeight, $srcWidth, $srcHeight); + } + } + else + { + if(!is_null($offsetx) && !is_null($offsety)) + { + JoomFile::fastImageCopyResampled( $dst_img, $src_img, 0, 0, $offsetx, $offsety, + $destWidth, (int)$destHeight, $srcWidth, $srcHeight); + } + else + { + JoomFile::fastImageCopyResampled( $dst_img, $src_img, 0, 0, 0, 0, $destWidth, + (int)$destHeight, $srcWidth, $srcHeight); + } + } + + if(!@imagejpeg($dst_img, $dest_file, $dest_qual)) + { + // Workaround for servers with wwwrun problem + $dir = dirname($dest_file); + JoomFile::chmod($dir, '0777', true); + imagejpeg($dst_img, $dest_file, $dest_qual); + JoomFile::chmod($dir, '0755', true); + } + imagedestroy($src_img); + imagedestroy($dst_img); + break; + case 'im': + $disabled_functions = explode(',', ini_get('disabled_functions')); + foreach($disabled_functions as $disabled_function) + { + if(trim($disabled_function) == 'exec') + { + $debugoutput .= JText::_('COM_JOOMGALLERY_UPLOAD_OUTPUT_EXEC_DISABLED').'
    '; + + return false; + } + } + + if(!empty($config->jg_impath)) + { + $convert_path=$config->jg_impath.'convert'; + } + else + { + $convert_path='convert'; + } + $commands = ''; + // Crop the source image before resiszing if offsets setted before + // example of crop: convert input -crop destwidthxdestheight+offsetx+offsety +repage output + // +repage needed to delete the canvas + if(!is_null($offsetx) && !is_null($offsety)) + { + $commands .= ' -crop "'.$srcWidth.'x'.$srcHeight.'+'.$offsetx.'+'.$offsety.'" +repage'; + } + // Finally the resize + $commands .= ' -resize "'.$destWidth.'x'.$destHeight.'" -quality "'.$dest_qual.'" -unsharp "3.5x1.2+1.0+0.10"'; + $convert = $convert_path.' '.$commands.' "'.$src_file.'" "'.$dest_file.'"'; + + $return_var = null; + $dummy = null; + @exec($convert, $dummy, $return_var); + if($return_var != 0) + { + // Workaround for servers with wwwrun problem + $dir = dirname($dest_file); + JoomFile::chmod($dir, '0777', true); + @exec($convert, $dummy, $return_var); + JoomFile::chmod($dir, '0755', true); + if($return_var != 0) + { + return false; + } + } + break; + default: + JError::raiseError(500, JText::_('COM_JOOMGALLERY_UPLOAD_UNSUPPORTED_RESIZING_METHOD')); + break; + } + + // Set mode of uploaded picture + JPath::setPermissions($dest_file); + + // We check that the image is valid + $imginfo = getimagesize($dest_file); + if(!$imginfo) + { + return false; + } + + return true; + } + + /** + * Fast resizing of images with GD2 + * Notice: need up to 3/4 times more memory + * http://de.php.net/manual/en/function.imagecopyresampled.php#77679 + * Plug-and-Play fastimagecopyresampled function replaces much slower + * imagecopyresampled. Just include this function and change all + * "imagecopyresampled" references to "fastimagecopyresampled". + * Typically from 30 to 60 times faster when reducing high resolution + * images down to thumbnail size using the default quality setting. + * Author: Tim Eckel - Date: 09/07/07 - Version: 1.1 - + * Project: FreeRingers.net - Freely distributable - These comments must remain. + * + * Optional "quality" parameter (defaults is 3). Fractional values are allowed, + * for example 1.5. Must be greater than zero. + * Between 0 and 1 = Fast, but mosaic results, closer to 0 increases the mosaic effect. + * 1 = Up to 350 times faster. Poor results, looks very similar to imagecopyresized. + * 2 = Up to 95 times faster. Images appear a little sharp, + * some prefer this over a quality of 3. + * 3 = Up to 60 times faster. Will give high quality smooth results very close to + * imagecopyresampled, just faster. + * 4 = Up to 25 times faster. Almost identical to imagecopyresampled for most images. + * 5 = No speedup. Just uses imagecopyresampled, no advantage over + * imagecopyresampled. + * + * @param string $dst_image path to destination image + * @param string $src_image path to source image + * @param int $dst_x destination x point left above + * @param int $dst_y destination y point left above + * @param int $src_x source x point left above + * @param int $src_y source y point left above + * @param int $dst_w destination width + * @param int $dst_h destination height + * @param int $src_w source width + * @param int $src_h source height + * @param int $quality quality of destination (fix = 3) read instructions above + * @return boolean True on success, false otherwise + * @since 1.0.0 + */ + public static function fastImageCopyResampled(&$dst_image, $src_image, $dst_x, $dst_y, + $src_x, $src_y, $dst_w, $dst_h, + $src_w, $src_h, $quality = 3) + { + if(empty($src_image) || empty($dst_image) || $quality <= 0) + { + return false; + } + + if($quality < 5 && (($dst_w * $quality) < $src_w || ($dst_h * $quality) < $src_h)) + { + $temp = imagecreatetruecolor($dst_w * $quality + 1, $dst_h * $quality + 1); + imagecopyresized ($temp, $src_image, 0, 0, $src_x, $src_y, $dst_w * $quality + 1, + $dst_h * $quality + 1, $src_w, $src_h); + imagecopyresampled($dst_image, $temp, $dst_x, $dst_y, 0, 0, $dst_w, + $dst_h, $dst_w * $quality, $dst_h * $quality); + imagedestroy ($temp); + } + else + { + imagecopyresampled($dst_image, $src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, + $dst_h, $src_w, $src_h); + } + return true; + } + + /** + * Copies an index.html file into a specified folder + * + * @param string The folder path to copy the index.html file into + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + public static function copyIndexHtml($folder) + { + jimport('joomla.filesystem.file'); + + $src = JPATH_ROOT.'/media/joomgallery/index.html'; + $dest = JPath::clean($folder.'/index.html'); + + return JFile::copy($src, $dest); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/helpers/helper.php b/deployed/joomgallery/administrator/components/com_joomgallery/helpers/helper.php new file mode 100644 index 00000000..017e53ee --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/helpers/helper.php @@ -0,0 +1,517 @@ + JText::_('COM_JOOMGALLERY_CONTROL_PANEL'), + 'categories' => JText::_('COM_JOOMGALLERY_CATEGORY_MANAGER'), + 'images' => JText::_('COM_JOOMGALLERY_IMAGE_MANAGER'), + 'comments' => JText::_('COM_JOOMGALLERY_COMMENTS_MANAGER'), + 'upload' => JText::_('COM_JOOMGALLERY_IMAGE_UPLOAD'), + 'ajaxupload' => JText::_('COM_JOOMGALLERY_AJAX_UPLOAD'), + 'batchupload' => JText::_('COM_JOOMGALLERY_BATCH_UPLOAD'), + 'ftpupload' => JText::_('COM_JOOMGALLERY_FTP_UPLOAD'), + 'jupload' => JText::_('COM_JOOMGALLERY_JAVA_UPLOAD'), + 'config' => JText::_('COM_JOOMGALLERY_CONFIGURATION_MANAGER'), + 'cssedit' => JText::_('COM_JOOMGALLERY_CUSTOMIZE_CSS'), + 'migration' => JText::_('COM_JOOMGALLERY_MIGRATION_MANAGER'), + 'maintenance' => JText::_('COM_JOOMGALLERY_MAINTENANCE_MANAGER'), + 'help' => JText::_('COM_JOOMGALLERY_HELP') + ); + + $canDo = self::getActions(); + + if(!JoomConfig::getInstance()->get('jg_disableunrequiredchecks') && !$canDo->get('joom.upload') && !count(JoomHelper::getAuthorisedCategories('joom.upload'))) + { + unset($controllers['upload']); + unset($controllers['batchupload']); + unset($controllers['ftpupload']); + unset($controllers['jupload']); + unset($controllers['ajaxupload']); + } + + if(!$canDo->get('core.admin')) + { + unset($controllers['config']); + unset($controllers['cssedit']); + unset($controllers['maintenance']); + } + + foreach($controllers as $controller => $title) + { + JHtmlSidebar::addEntry( $title, + 'index.php?option='._JOOM_OPTION.'&controller='.$controller, + $controller == $current_controller + ); + } + } + + /** + * Returns a list of the actions that can be performed + * + * @param string $type The type of the content to check + * @param int $id The ID of the content (category or image) + * @return JObject An object holding the results of the check + * @since 2.0 + */ + public static function getActions($type = 'component', $id = 0) + { + static $cache = array(); + + // Create a unique key for the this pair of parameters + $key = $type.':'.$id; + + if(isset($cache[$key])) + { + return $cache[$key]; + } + + $user = JFactory::getUser(); + $result = new JObject(); + + $actions = array('core.admin', 'core.manage', 'joom.upload', 'joom.upload.inown', 'core.create', 'joom.create.inown', 'core.edit', 'core.edit.own', 'core.edit.state', 'core.delete'); + + switch($type) + { + case 'category': + $assetName = _JOOM_OPTION.'.category.'.$id; + break; + case 'image': + $assetName = _JOOM_OPTION.'.image.'.$id; + break; + default: + $assetName = _JOOM_OPTION; + break; + } + + foreach($actions as $action) + { + $result->set($action, $user->authorise($action, $assetName)); + } + + // Store the result for better performance + $cache[$key] = $result; + + return $result; + } + + /** + * Returns a list of all categories for that a user has permission for a given action + * + * @param string $action The action to check for + * @return array List of category objects for which the current can do the selected action to (empty array if none) + * @since 2.0 + */ + public static function getAuthorisedCategories($action) + { + $user = JFactory::getUser(); + $cats = JoomAmbit::getInstance()->getCategoryStructure(true); + $allowedCategories = array(); + foreach($cats as $category) + { + $action2 = false; + if($action == 'joom.upload') + { + $action2 = 'joom.upload.inown'; + } + if($action == 'core.create') + { + $action2 = 'joom.create.inown'; + } + if($action == 'core.edit') + { + $action2 = 'core.edit.own'; + } + + if( $user->authorise($action, _JOOM_OPTION.'.category.'.$category->cid) + || ( $action2 + && $category->owner == $user->get('id') + && $user->authorise($action2, _JOOM_OPTION.'.category.'.$category->cid) + ) + ) + { + $allowedCategories[] = $category; + } + } + + return $allowedCategories; + } + + /** + * Returns all parent categories of a specific category + * + * @param int $category The ID of the specific child category + * @param boolean $child True, if category itself shall also be returned, defaults to false + * @return array An array of parent category objects with cid,name,parent_id + * @since 1.5.5 + */ + public static function getAllParentCategories($category, $child = false) + { + // Get category structure from ambit + $ambit = JoomAmbit::getInstance(); + $cats = $ambit->getCategoryStructure(); + $parents = array(); + + if(!$category) + { + return $parents; + } + + if($child) + { + $parents[$category] = new stdClass(); + $parents[$category]->cid = $cats[$category]->cid; + $parents[$category]->name = $cats[$category]->name; + $parents[$category]->parent_id = $cats[$category]->parent_id; + $parents[$category]->published = $cats[$category]->published; + } + + $parentcat = $cats[$category]->parent_id; + while($parentcat != 1) + { + $category = $parentcat; + $parents[$category] = new stdClass(); + $parents[$category]->cid = $cats[$category]->cid; + $parents[$category]->name = $cats[$category]->name; + $parents[$category]->parent_id = $cats[$category]->parent_id; + $parents[$category]->published = $cats[$category]->published; + $parentcat = $cats[$category]->parent_id; + } + + // Reverse the array to get the right order + $parents = array_reverse($parents, true); + + return $parents; + } + + /** + * Returns all categories and their sub-categories with published or no images + * + * @param int $cat Category ID + * @param boolean $rootcat True, if $cat shall also be returned as an + * element of the array + * @param boolean $noimgcats True if @return shall also include categories + * with no images + * @param boolean $all True if all categories shall be selected, defaults to true + * @param boolean $nohiddencats True, if sub-categories of hidden categories should be + * filtered out, defaults to false + * @return array An array of found categories + * @since 1.5.5 + */ + public static function getAllSubCategories($cat, $rootcat = false, $noimgcats = false, $all = true, $nohiddencats = false) + { + // Initialise variables + $cat = (int) $cat; + $parentcats = array(); + $parentcats[$cat] = true; + $branchfound = false; + $allsubcats = array(); + + // Get category structure from ambit + $ambit = JoomAmbit::getInstance(); + $cats = $ambit->getCategoryStructure($all); + + $stopindex = count($cats); + + $keys = array_keys($cats); + $startindex = array_search($cat, $keys); + if($startindex === false) + { + return $allsubcats; + } + + // Find all cats which are subcategories of cat + $hidden = array(); + for($j = $startindex + 1; $j < $stopindex; $j++) + { + $i = $keys[$j]; + $parentcat = $cats[$i]->parent_id; + if(isset($parentcats[$parentcat])) + { + $parentcats[$i] = true; + $branchfound = true; + + // Don't include hidden sub-categories + if($nohiddencats) + { + if($cats[$i]->hidden) + { + $hidden[$i] = true; + } + else + { + if(isset($hidden[$cats[$i]->parent_id])) + { + $hidden[$i] = true; + } + } + } + + if(!isset($hidden[$i])) + { + if(!$noimgcats) + { + // Only categories with images + if($cats[$i]->piccount > 0) + { + // Subcategory with images in array + $allsubcats[] = $i; + } + } + else + { + $allsubcats[] = $i; + } + } + } + else + { + if($branchfound) + { + // Branch has been processed completely + break; + } + } + } + + // Add rootcat + if($rootcat) + { + if(!$noimgcats) + { + // Includes images + if($cats[$cat]->piccount > 0) + { + $allsubcats[] = $cat; + } + } + else + { + $allsubcats[] = $cat; + } + } + + return $allsubcats; + } + + /** + * Wrap text + * + * @param string $text Text to wrap + * @param int $nr Number of chars to wrap + * @return string Wrapped text + * @since 1.0.0 + */ + public static function processText($text, $nr = 40) + { + $mytext = explode(' ', trim($text)); + $newtext = array(); + foreach($mytext as $k => $txt) + { + if(strlen($txt) > $nr) + { + $txt = wordwrap($txt, $nr, '- ', 1); + } + $newtext[] = $txt; + } + + return implode(' ', $newtext); + } + + /** + * Reads the category path from array. + * If not set read db and add to array. + * + * @param int $catid The ID of the category + * @return string The category path + * @since 1.0.0 + */ + public static function getCatPath($catid) + { + static $catpath = array(); + + if(!isset($catpath[$catid])) + { + $database = JFactory::getDBO(); + + $query = $database->getQuery(true) + ->select('catpath') + ->from(_JOOM_TABLE_CATEGORIES) + ->where('cid= '.$catid); + + $database->setQuery($query); + if(!$path = $database->loadResult()) + { + $catpath[$catid] = ''; + } + else + { + $catpath[$catid] = $path.'/'; + } + } + + return $catpath[$catid]; + } + + /** + * Returns the rating clause for an SQL - query dependent on the + * rating calculation method selected. + * + * @param string $tablealias Table alias + * @return string Rating clause + * @since 1.5.6 + */ + public static function getSQLRatingClause($tablealias = '') + { + $db = JFactory::getDBO(); + $config = JoomConfig::getInstance(); + static $avgimgvote = 0.0; + static $avgimgrating = 0.0; + static $avgdone = false; + + $maxvoting = $config->get('jg_maxvoting'); + $imgvotesum = 'imgvotesum'; + $imgvotes = 'imgvotes'; + if($tablealias != '') + { + $imgvotesum = $tablealias.'.'.$imgvotesum; + $imgvotes = $tablealias.'.'.$imgvotes; + } + + // Standard rating clause + $clause = 'ROUND(LEAST(IF(imgvotes > 0, '.$imgvotesum.'/'.$imgvotes.', 0.0), '.(float)$maxvoting.'), 2)'; + + // Advanced (weigthed) rating clause (Bayes) + if($config->get('jg_ratingcalctype') == 1) + { + if(!$avgdone) + { + // Needed values for weighted rating calculation + $query = $db->getQuery(true) + ->select('count(*) As imgcount') + ->select('SUM(imgvotes) As sumimgvotes') + ->select('SUM(imgvotesum/imgvotes) As sumimgratings') + ->from(_JOOM_TABLE_IMAGES) + ->where('imgvotes > 0'); + + $db->setQuery($query); + $row = $db->loadObject(); + if($row != null) + { + if($row->imgcount > 0) + { + $avgimgvote = round($row->sumimgvotes / $row->imgcount, 2 ); + $avgimgrating = round($row->sumimgratings / $row->imgcount, 2); + $avgdone = true; + } + } + } + if($avgdone) + { + $clause = 'ROUND(LEAST(IF(imgvotes > 0, (('.$avgimgvote.'*'.$avgimgrating.') + '.$imgvotesum.') / ('.$avgimgvote.' + '.$imgvotes.'), 0.0), '.(float)$maxvoting.'), 2)'; + } + } + + return $clause; + } + /** + * Returns the rating of an image + * + * @param string $imgid Image id to get the rating for + * @return float Rating + * @since 1.5.6 + */ + public static function getRating($imgid) + { + $db = JFactory::getDBO(); + $rating = 0.0; + + $query = $db->getQuery(true) + ->select(JoomHelper::getSQLRatingClause().' AS rating') + ->from(_JOOM_TABLE_IMAGES) + ->where('id = '.$imgid); + + $db->setQuery($query); + if(($result = $db->loadResult()) != null) + { + $rating = $result; + } + + return $rating; + } + + /** + * Converts a given size with units e.g. read from php.ini to bytes. + * + * @param string $val Value with units (e.g. 8M) + * @return int Value in bytes + * @since 3.0 + */ + + public static function iniToBytes($val) + { + $val = trim($val); + + switch(strtolower(substr($val, -1))) + { + case 'm': + $val = (int)substr($val, 0, -1) * 1048576; + break; + case 'k': + $val = (int)substr($val, 0, -1) * 1024; + break; + case 'g': + $val = (int)substr($val, 0, -1) * 1073741824; + break; + case 'b': + switch(strtolower(substr($val, -2, 1))) + { + case 'm': + $val = (int)substr($val, 0, -2) * 1048576; + break; + case 'k': + $val = (int)substr($val, 0, -2) * 1024; + break; + case 'g': + $val = (int)substr($val, 0, -2) * 1073741824; + break; + default: + break; + } + break; + default: + break; + } + + return $val; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/helpers/html/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/helpers/html/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/helpers/html/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/helpers/html/joomconfig.php b/deployed/joomgallery/administrator/components/com_joomgallery/helpers/html/joomconfig.php new file mode 100644 index 00000000..31006d74 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/helpers/html/joomconfig.php @@ -0,0 +1,109 @@ + +
    + + +
    +
    + + +
    + + textfield, 'yesno' => yes/no selectbox, 'custom' => custom selectbox or textfield + * @param $name string language constant for the title and the description (+_LONG) of the option, will be translated + * @param $info string/int current setting of the option, if $type = 'custom', we will assume that it holds the complete HTML string + * @param $display boolean if set to false, we won't display this option, defaults to true + * @param $attribs string additional tag attributes (e.g. size = "50"), for now only effective for type 'text' + * @param $text string Alternative description text, if null the default language constant will be used for each option + */ + public static function row($key, $type, $name, $info, $display = true, $attribs = '', $text = null) + { + if(!$display) + { + return; + } +?> + + + /> + + +useruploaded) && $row->useruploaded) + || + (!isset($row->useruploaded) && $row->owner) + ) + { + $img = 'users.png'; + $title = JText::_($user_uploaded); + } + else + { + $img = 'admin.png'; + $title = JText::_($admin_uploaded); + } + + $imgsrc = $ambit->getIcon($img); + $html = ''.$title.'' + ; + + return $html; + } + + /** + * Displays the name or user name of a category, image or comment owner + * and may link it to the profiles of other extensions (if available). + * + * @param int $userId The ID of the user who will be displayed + * @param boolean $context The context in which the user will be dispayed + * @return string The user's name + * @since 1.5.5 + */ + public static function displayName($userId, $context = null) + { + $userId = intval($userId); + + if(!$userId) + { + if(JFactory::getApplication()->isSite()) + { + return JText::_('COM_JOOMGALLERY_COMMON_NO_DATA'); + } + else + { + return JText::_('COM_JOOMGALLERY_COMMON_NO_USER'); + } + } + + $config = JoomConfig::getInstance(); + $dispatcher = JDispatcher::getInstance(); + + $realname = $config->get('jg_realname') ? true : false; + + $plugins = $dispatcher->trigger('onJoomDisplayUser', array($userId, $realname, $context)); + + foreach($plugins as $plugin) + { + if($plugin) + { + return $plugin; + } + } + + $user = JFactory::getUser($userId); + + if($realname) + { + $username = $user->get('name'); + } + else + { + $username = $user->get('username'); + } + + return $username; + } + + /** + * Fires onPrepareContent for a text if configured in the gallery + * + * @param string $text The text to be transformed. + * @return string The text after transformation. + * @since 1.5.5 + */ + public static function text($text) + { + $config = JoomConfig::getInstance(); + + if($config->get('jg_contentpluginsenabled')) + { + $text = JHTML::_('content.prepare', $text); + } + + return $text; + } + + /** + * Returns the HTML tag of a specified icon + * + * @param string $icon Filename of the icon + * @param string $alt Alternative text of the icon + * @param string $extra Additional HTML code in the tag + * @param string $path Path to the icon, if null the default path is used + * @param boolean $translate Determines whether the text will be translated, defaults to true. + * @return string The HTML output + * @since 1.5.5 + */ + public static function icon($icon, $alt = 'Icon', $extra = null, $path = null, $translate = true) + { + if(is_null($path)) + { + $ambit = JoomAmbit::getInstance(); + $path = $ambit->get('icon_url'); + + // Make the icons overridable by layout packages + if($layout = $ambit->get('layout')) + { + if(is_file(JPATH_ROOT.'/media/joomgallery/images/'.$layout.'/'.$icon)) + { + $path = $path.$layout.'/'; + } + } + } + + if($extra) + { + $extra = ' '.$extra; + } + + if($translate) + { + $alt = JText::_($alt); + } + + $class = 'jg-icon-'.str_replace(array('.jpg', '.png', '.gif'), '', $icon); + + return ''.$alt.''; + } + + /** + * Displays the toplist bar + * + * @return void + * @since 1.5.5 + */ + public static function toplistbar() + { + $config = JoomConfig::getInstance(); + $separator = " -\n"; + + echo JText::sprintf('COM_JOOMGALLERY_TOPLIST_TOP', $config->get('jg_toplist')); ?> +get('jg_showrate')) + { +?> + + +get('jg_showlatest') || $config->get('jg_showcom') || $config->get('jg_showmostviewed')) + { + echo $separator; + } + } + if($config->get('jg_showlatest')) + { +?> + + +get('jg_showcom') || $config->get('jg_showmostviewed')) + { + echo $separator; + } + } + if($config->get('jg_showcom')) + { +?> + + +get('jg_showmostviewed')) + { + echo $separator; + } + } + if($config->get('jg_showmostviewed')) + { +?> + + +get('jg_nameshields_width'); + + $html = ''; + $i = 1; + foreach($rows as $row) + { + $name = JHTMLJoomGallery::displayName($row->nuserid, 'nametag'); + $length = strlen(trim(strip_tags($name))) * $width; + + $icon = ''; + $html .= '
    nid.'" class="jg-nametag-remove-icon jg_displaynone" href="javascript:if(confirm(\''.JText::_('COM_JOOMGALLERY_DETAIL_NAMETAGS_ALERT_SURE_DELETE_OTHERS', true).'\')){ location.href=\''.JRoute::_('index.php?task=nametags.remove&id='.$row->npicid.'&nid='.$row->nid, false).'\';}">' + .JHTML::_('joomgallery.icon', 'tag_delete.png', 'COM_JOOMGALLERY_DETAIL_NAMETAGS_DELETE_OTHERS_TIPCAPTION').''; + } + //} + $html .= '">'; + $html .= $name; + $html .= '
    '; + $html .= $icon; + + $i++; + } + + return $html; + } + + /** + * Returns the string of an anchor for a URL if using anchors is enabled + * + * @param string $name Name of the anchor + * @return string The string of the anchor + * @since 1.5.5 + */ + public static function anchor($name = 'joomimg') + { + $config = JoomConfig::getInstance(); + + $anchor = ''; + if($name && $config->get('jg_anchors')) + { + $anchor = '#'.$name; + } + + return $anchor; + } + + /** + * Returns the HTML output of a tooltip if showing tooltips is enabled + * + * @param string $text The text of the tooltip + * @param string $title The title of the tooltip + * @param boolean $addclass True, if the class attribute shall be added and false if it's already there + * @param boolean $translate True, if the text and the title shall be translated + * @param string $class The name of the class used by Mootools to detect the tooltips + * @return string The HTML output created + * @since 1.5.5 + */ + public static function tip($text = 'Tooltip', $title = null, $addclass = false, $translate = true, $class = 'hasHint') + { + $config = JoomConfig::getInstance(); + + $html = ''; + if($config->get('jg_tooltips')) + { + static $loaded = false; + + if(!$loaded) + { + $params = array(); + if($config->get('jg_tooltips') == 2) + { + $params['template'] = '
    '; + } + + JHtml::_('bootstrap.tooltip', '.'.$class, $params); + $loaded = true; + } + + if($config->get('jg_tooltips') == 2) + { + $tmp = ""; + if($title) + { + $tmp = '
    '; + + if($translate) + { + $title = JText::_($title); + } + + $tmp .= $title . '
    '; + } + + $tmp .= '
    ' . ($translate ? JText::_($text) : $text) . '
    '; + $text = htmlspecialchars($tmp, ENT_QUOTES, 'UTF-8'); + } + else + { + $text = JHtml::tooltipText($title, $text, $translate); + } + + if($addclass) + { + $html = ' class="'.$class.'" title="'.$text.'"'; + } + else + { + $html = ' '.$class.'" title="'.$text; + } + } + + return $html; + } + + /** + * Creates invisible links to images in order that + * the popup boxes recognize them + * + * @param array $rows An array of image objects to use + * @param int $start Index of the first image to use + * @param int $end Index of the last image to use, if null we will use every image from $start to end + * @param string $secondGroup Name of an optional second group, by specifying a second group all links will be duplicated with that group + * @return string The HTML output + * @since 1.5.5 + */ + public static function popup(&$rows, $start = 0, $end = null, $secondGroup = null) + { + $config = JoomConfig::getInstance(); + $ambit = JoomAmbit::getInstance(); + $user = JFactory::getUser(); + $view = JRequest::getCmd('view'); + + $html = ''; + + if( ( $view == 'category' + // 'jg_detailpic_open' is not numeric if an OpenImage plugin was selected, thus we handle it like > 4 + && (!is_numeric($config->get('jg_detailpic_open')) || $config->get('jg_detailpic_open') > 4) + && ( $config->get('jg_showdetailpage') == 1 + || ($config->get('jg_showdetailpage') == 0 && $user->get('id')) + ) + ) + || + ( $view == 'detail' + && ( ($config->get('jg_bigpic') == 1 && $user->get('id')) + || ($config->get('jg_bigpic_unreg') == 1 && !$user->get('id')) + ) + // 'jg_bigpic_open' is not numeric if an OpenImage plugin was selected, thus we handle it like > 4 + && (!is_numeric($config->get('jg_bigpic_open')) || $config->get('jg_bigpic_open') > 4) + ) + ) + { + if(is_null($end)) + { + $rows = array_slice($rows, (int)$start); + } + else + { + $rows = array_slice($rows, (int)$start, (int)$end); + } + + $html = '
    '; + + foreach($rows as $row) + { + if( ($view == 'detail' && is_file($ambit->getImg('orig_path', $row))) + || $view == 'category' + ) + { + if($view == 'detail') + { + $type = $config->get('jg_bigpic_open'); + } + else + { + $type = $config->get('jg_detailpic_open'); + } + + // Set the title attribute in a tag with title and/or description of image + // if a box is activated + if(!is_numeric($type) || $type > 1) + { + $atagtitle = JHtml::_('joomgallery.getTitleforATag', $row); + } + else + { + $atagtitle = 'title="'.$row->imgtitle.'"'; + } + + $link = self::openImage($type, $row); + $html .= ' + '.$row->id.''; + + if($secondGroup) + { + $link = self::openImage($type, $row, false, $secondGroup); + $html .= ' + '.$row->id.''; + } + } + } + $html .= ' +
    '; + } + + return $html; + } + + /** + * Returns the title attribute of HTML a tag + * + * @param object $image The object which holds the image data + * @param boolean $attr True if title attribute should be returned completely, + * if false only the content is returned, defaults to true + * @return string The title attribute of HTML a Tag + * @since 2.0 + */ + public static function getTitleforATag($image, $attr = true) + { + $config = JoomConfig::getInstance(); + + $tagtitle = ''; + $tagdesc = ''; + if( $config->get('jg_show_title_in_popup') + || $config->get('jg_show_description_in_popup')) + { + if($config->get('jg_show_title_in_popup')) + { + $tagtitle = $image->imgtitle; + } + + if( $config->get('jg_show_description_in_popup') + && !empty($image->imgtext)) + { + if($config->get('jg_show_description_in_popup') == 1) + { + // Show description without html tag modifications + $tagdesc = htmlspecialchars($image->imgtext); + } + else + { + // Strip html tags of description before + $tagdesc = strip_tags($image->imgtext); + } + } + + if(!empty($tagdesc)) + { + if(!empty($tagtitle)) + { + $tagtitle .= ' '.$tagdesc; + } + else + { + $tagtitle = $tagdesc; + } + } + + if(!empty($tagtitle) && $attr) + { + $tagtitle = 'title="'.$tagtitle.'"'; + } + } + + return $tagtitle; + } + + /** + * Returns the link to a given image, which opens the image in slimbox, for example + * + * @param int $open Use of lightbox, javascript window or DHTML container? + * @param int/object $image The id of the image or an object which holds the image data + * @param string $type The image type ('thumb', 'img', 'orig'), use 'false' for default value + * @param string $group Name of a group to group images in the popups + * @return string The link to the image + * @since 1.0.0 + */ + public static function openImage($open, $image, $type = false, $group = null) + { + static $loaded = array(); + + $config = JoomConfig::getInstance(); + $ambit = JoomAmbit::getInstance(); + $user = JFactory::getUser(); + + // No detail view for guests if adjusted like that + if(!$config->get('jg_showdetailpage') && !$user->get('id')) + { + return 'javascript:alert(\''.JText::_('COM_JOOMGALLERY_COMMON_ALERT_NO_DETAILVIEW_FOR_GUESTS', true).'\')'; + } + + if(!is_object($image)) + { + $image = $ambit->getImgObject($image); + } + + if(!$type) + { + // 'jg_detailpic_open' is not numeric if an OpenImage plugin was selected, thus we handle it like > 4 + if( (!is_numeric($config->get('jg_detailpic_open')) || $config->get('jg_detailpic_open') > 4) + && $config->get('jg_lightboxbigpic') + ) + { + $type = 'orig'; + } + else + { + if(JRequest::getCmd('view') == 'detail') + { + $type = 'orig'; + } + else + { + $type = 'img'; + } + } + } + + if(!$group) + { + $group = 'joomgallery'; + } + + $img_url = $ambit->getImg($type.'_url', $image); + $img_path = $ambit->getImg($type.'_path', $image); + + switch($open) + { + case '0': // Detail view + $link = JRoute::_('index.php?view=detail&id='.$image->id); + break; + case 1: // New window + $link = $img_url."\" target=\"_blank"; + break; + case 2: // JavaScript window + $imginfo = getimagesize($img_path); + $link = "javascript:joom_openjswindow('".$img_url."','".JoomHelper::fixForJS($image->imgtitle)."', '".$imginfo[0]."','".$imginfo[1]."')"; + + if(!isset($loaded[2])) + { + $doc = JFactory::getDocument(); + $doc->addScript($ambit->getScript('jswindow.js')); + $script = ' var resizeJsImage = '.$config->get('jg_resize_js_image').'; + var jg_disableclick = '.$config->get('jg_disable_rightclick_original').';'; + $doc->addScriptDeclaration($script); + $loaded[2] = true; + } + break; + case 3: // DHTML container + $imginfo = getimagesize($img_path); + $link = "javascript:joom_opendhtml('".$img_url."','"; + + if($config->get('jg_show_title_in_popup')) + { + $link .= JoomHelper::fixForJS($image->imgtitle)."','"; + } + else + { + $link .= "','"; + } + if($config->get('jg_show_description_in_popup')) + { + if($config->get('jg_show_description_in_popup') == 1) + { + $link .= JoomHelper::fixForJS($image->imgtext)."','"; + } + else + { + $link .= JoomHelper::fixForJS(strip_tags($image->imgtext))."','"; + } + } + else + { + $link .= "','"; + } + $link .= $imginfo[0]."','".$imginfo[1]."','".JUri::root()."')"; + + if(!isset($loaded[3])) + { + $doc = JFactory::getDocument(); + $doc->addScript($ambit->getScript('dhtml.js')); + $script = ' var resizeJsImage = '.$config->get('jg_resize_js_image').'; + var jg_padding = '.$config->jg_openjs_padding.'; + var jg_dhtml_border = "'.$config->jg_dhtml_border.'"; + var jg_openjs_background = "'.$config->jg_openjs_background.'"; + var jg_disableclick = '.$config->jg_disable_rightclick_original.';'; + $doc->addScriptDeclaration($script); + $loaded[3] = true; + } + break; + case 4: // Modalbox + #$imginfo = getimagesize($img_path); + $link = $img_url.'" class="modal" rel="'./*{handler: 'iframe', size: {x: ".$imginfo[0].", y: ".$imginfo[1]."}}*/'" title="'.$image->imgtitle; + + if(!isset($loaded[4])) + { + JHtml::_('behavior.framework'); // Loads mootools only, if it hasn't already been loaded + JHTML::_('behavior.modal'); + $loaded[4] = true; + } + break; + case 5: // Thickbox3 + $link = $img_url.'" rel="thickbox.'.$group; + + if(!isset($loaded[5])) + { + $doc = JFactory::getDocument(); + + JHtml::_('jquery.framework'); + $doc->addScript($ambit->getScript('thickbox3/js/thickbox.js')); + $doc->addStyleSheet($ambit->getScript('thickbox3/css/thickbox.css')); + $script = ' var resizeJsImage = '.$config->get('jg_resize_js_image').'; + var joomgallery_image = "'.JText::_('COM_JOOMGALLERY_COMMON_IMAGE', true).'"; + var joomgallery_of = "'.JText::_('COM_JOOMGALLERY_POPUP_OF', true).'"; + var joomgallery_close = "'.JText::_('COM_JOOMGALLERY_POPUP_CLOSE', true).'"; + var joomgallery_prev = "'.JText::_('COM_JOOMGALLERY_POPUP_PREVIOUS', true).'"; + var joomgallery_next = "'.JText::_('COM_JOOMGALLERY_POPUP_NEXT', true).'"; + var joomgallery_press_esc = "'.JText::_('COM_JOOMGALLERY_POPUP_ESC', true).'"; + var tb_pathToImage = "'.$ambit->getScript('thickbox3/images/loadingAnimation.gif').'";'; + $doc->addScriptDeclaration($script); + $loaded[5] = true; + } + break; + case 6: // Slimbox + $link = $img_url.'" rel="lightbox['.$group.']'; + + if(!isset($loaded[6])) + { + $doc = JFactory::getDocument(); + JHtml::_('behavior.framework'); // Loads mootools only, if it hasn't already been loaded + $doc->addScript($ambit->getScript('slimbox/js/slimbox.js')); + $doc->addStyleSheet($ambit->getScript('slimbox/css/slimbox.css')); + $script = ' var resizeJsImage = '.$config->get('jg_resize_js_image').'; + var resizeSpeed = '.$config->get('jg_lightbox_speed').'; + var joomgallery_image = "'.JText::_('COM_JOOMGALLERY_COMMON_IMAGE', true).'"; + var joomgallery_of = "'.JText::_('COM_JOOMGALLERY_POPUP_OF', true).'";'; + $doc->addScriptDeclaration($script); + $loaded[6] = true; + } + break; + default: // Plugins + if(!isset($loaded[12])) + { + $loaded[12] = JDispatcher::getInstance(); + } + $link = ''; + $loaded[12]->trigger('onJoomOpenImage', array(&$link, $image, $img_url, $group, $type, $open)); + if(!$link) + { + // Fallback to new window + $link = $img_url."\" target=\"_blank"; + } + break; + } + + return $link; + } + + /** + * Creates a JavaScript tree with all sub-categories of a category + * + * @param int $rootcatid The category ID + * @param string $align Alignment of the tree + * @return void + * @since 1.5.0 + */ + public static function categoryTree($rootcatid, $align) + { + $ambit = JoomAmbit::getInstance(); + $config = JoomConfig::getInstance(); + $user = JFactory::getUser(); + $categories = $ambit->getCategoryStructure(true); + + // Check access rights settings + $filter_cats = false; + $restricted_hint = false; + $restricted_cats = false; + $root_access = false; + if(!$config->get('jg_showrestrictedhint') && !$config->get('jg_showrestrictedcats')) + { + $filter_cats = true; + } + else + { + if($config->get('jg_showrestrictedhint')) + { + $restricted_hint = true; + } + if($config->get('jg_showrestrictedcats')) + { + $restricted_cats = true; + } + } + + // Array to hold the relevant sub-category objects + $subcategories = array(); + // Array to hold the valid parent categories + $validParentCats = array(); + $validParentCats[$rootcatid] = true; + + // Get all relevant subcategories + $keys = array_keys($categories); + $startindex = array_search($rootcatid, $keys); + if($startindex !== false) + { + $stopindex = count($categories); + $root_access = in_array($categories[$rootcatid]->access, $user->getAuthorisedViewLevels()) && !$categories[$rootcatid]->protected; + + for($j = $startindex + 1; $j < $stopindex; $j++) + { + $i = $keys[$j]; + $parentcat = $categories[$i]->parent_id; + if(isset($validParentCats[$parentcat])) + { + // Hide empty categories + $empty = false; + if($config->get('jg_hideemptycats')) + { + $subcatids = JoomHelper::getAllSubCategories($i, true, ($config->get('jg_hideemptycats') == 1), true); + // If 'jg_hideemptycats' is set to 1 the root category will always be in $subcatids, so check whether there are images in it + if( !count($subcatids) + || (count($subcatids) == 1 && $config->get('jg_hideemptycats') == 1 && !$categories[$i]->piccount) + ) + { + $empty = true; + } + } + + if( $categories[$i]->published + && ($filter_cats == false || ( + in_array($categories[$i]->access, $user->getAuthorisedViewLevels()) + && (($parentcat == $rootcatid && $root_access) || ($parentcat != $rootcatid && $subcategories[$parentcat]->access)) + ) + ) + && !$categories[$i]->hidden + && (!$config->get('jg_hideemptycats') || !$empty) + ) + { + $validParentCats[$i] = true; + $subcategories[$i] = clone $categories[$i]; + if( + ( $parentcat == $rootcatid + && !$root_access + ) + || + ( $parentcat != $rootcatid + && + !$subcategories[$parentcat]->access + ) + || !in_array($categories[$i]->access, $user->getAuthorisedViewLevels()) + || $categories[$i]->protected + ) + { + $subcategories[$i]->access = false; + + if( + ( $parentcat == $rootcatid + && !$root_access + ) + || + ( $parentcat != $rootcatid + && + !$subcategories[$parentcat]->access + ) + ) + { + $subcategories[$i]->protected = false; + } + } + } + } + else + { + if($parentcat == 0) + { + // Branch has been processed completely + break; + } + } + } + } + + // Show the treeview + $count = count($subcategories); + if(!$count) + { + return; + } + + // If $align is 'jg_element_txt' we are displaying random thumbnails + // or the thumbnail alignment is set to 'Use global'. In both cases + // we have to take 'jg_ctalign' under consideration. + if($align == 'jg_element_txt') + { + switch($config->get('jg_ctalign')) + { + case 0: + // Changing: $align is only 'jg_element_txt' if the thumbnail is aligned left + // Break omitted intentionally + case 1: + // Left + $align = 'jg_element_txt_l'; + break; + case 2: + // Right + $align = 'jg_element_txt_r'; + break; + case 3: + // Break omitted intentionally + default: + // Centered + $align = 'jg_element_txt_c'; + break; + } + } + + if($align == 'jg_element_txt_l') + { +?> +
    + +
    + +
    + + + + + +
    + +
    +
    +get('jg_maxvoting'); + + // Standard rating output as text + if($config->get('jg_ratingdisplaytype') == 0) + { + $rating = number_format((float) $image->rating, 2, JText::_('COM_JOOMGALLERY_COMMON_DECIMAL_SEPARATOR'), JText::_('COM_JOOMGALLERY_COMMON_THOUSANDS_SEPARATOR')); + if($image->imgvotes > 0) + { + if($image->imgvotes == 1) + { + $html = $rating.' ('.$image->imgvotes.' '. JText::_('COM_JOOMGALLERY_COMMON_ONE_VOTE') . ')'; + } + else + { + $html = $rating.' ('.$image->imgvotes.' '. JText::_('COM_JOOMGALLERY_COMMON_VOTES') . ')'; + } + } + else + { + $html = JText::_('COM_JOOMGALLERY_COMMON_NO_VOTES'); + } + if(!$shortText) + { + $html = JText::sprintf('COM_JOOMGALLERY_COMMON_RATING_VAR', $html); + } + // Same as   but   also works in XML + $html .= ' '; + } + + // Rating output with star images + if($config->get('jg_ratingdisplaytype') == 1) + { + $width = 0; + if($config->get('jg_maxvoting') > 0 && $image->imgvotes > 0) + { + $width = (int) ($image->rating / (float) $config->get('jg_maxvoting') * 100.0); + } + + if(isset($tooltipclass)) + { + $html .= '
    '; + } + else + { + $html .= '
    '; + } + $html .= '
    '; + $html .= '
    '; + } + + return $html; + } + + /** + * Replace bbcode tags (b/u/i/url/email) with HTML tags + * + * @param string $text The text to be modified + * @return string The modified text + * @since 1.0.0 + */ + public static function BBDecode($text) + { + static $bbcode_tpl = array(); + static $patterns = array(); + static $replacements = array(); + + // First: If there isn't a "[" and a "]" in the message, don't bother. + if((strpos($text, '[') === false || strpos($text, ']') === false)) + { + return $text; + } + + // [b] and [/b] for bolding text. + $text = str_replace('[b]', '', $text); + $text = str_replace('[/b]', '', $text); + + // [u] and [/u] for underlining text. + $text = str_replace('[u]', '', $text); + $text = str_replace('[/u]', '', $text); + + // [i] and [/i] for italicizing text. + $text = str_replace('[i]', '', $text); + $text = str_replace('[/i]', '', $text); + + if(!count($bbcode_tpl)) + { + // We do URLs in several different ways.. + $bbcode_tpl['url'] = '{DESCRIPTION}'; + $bbcode_tpl['email'] = '{EMAIL}'; + $bbcode_tpl['url1'] = str_replace('{URL}', '\\1\\2', $bbcode_tpl['url']); + $bbcode_tpl['url1'] = str_replace('{DESCRIPTION}', '\\1\\2', $bbcode_tpl['url1']); + $bbcode_tpl['url2'] = str_replace('{URL}', 'http://\\1', $bbcode_tpl['url']); + $bbcode_tpl['url2'] = str_replace('{DESCRIPTION}', '\\1', $bbcode_tpl['url2']); + $bbcode_tpl['url3'] = str_replace('{URL}', '\\1\\2', $bbcode_tpl['url']); + $bbcode_tpl['url3'] = str_replace('{DESCRIPTION}', '\\3', $bbcode_tpl['url3']); + $bbcode_tpl['url4'] = str_replace('{URL}', 'http://\\1', $bbcode_tpl['url']); + $bbcode_tpl['url4'] = str_replace('{DESCRIPTION}', '\\2', $bbcode_tpl['url4']); + $bbcode_tpl['email'] = str_replace('{EMAIL}', '\\1', $bbcode_tpl['email']); + + // [url]xxxx://www.phpbb.com[/url] code.. + $patterns[1] = '#\[url\]([a-z]+?://){1}([a-z0-9\-\.,\?!%\*_\#:;~\\&$@\/=\+\(\)]+)\[/url\]#si'; + $replacements[1] = $bbcode_tpl['url1']; + // [url]www.phpbb.com[/url] code.. (no xxxx:// prefix). + $patterns[2] = '#\[url\]([a-z0-9\-\.,\?!%\*_\#:;~\\&$@\/=\+\(\)]+)\[/url\]#si'; + $replacements[2] = $bbcode_tpl['url2']; + // [url=xxxx://www.phpbb.com]phpBB[/url] code.. + $patterns[3] = '#\[url=([a-z]+?://){1}([a-z0-9\-\.,\?!%\*_\#:;~\\&$@\/=\+\(\)]+)\](.*?)\[/url\]#si'; + $replacements[3] = $bbcode_tpl['url3']; + // [url=www.phpbb.com]phpBB[/url] code.. (no xxxx:// prefix). + $patterns[4] = '#\[url=([a-z0-9\-\.,\?!%\*_\#:;~\\&$@\/=\+\(\)]+)\](.*?)\[/url\]#si'; + $replacements[4] = $bbcode_tpl['url4']; + //[email]user@domain.tld[/email] code.. + $patterns[5] = '#\[email\]([a-z0-9\-_.]+?@[\w\-]+\.([\w\-\.]+\.)?[\w]+)\[/email\]#si'; + $replacements[5] = $bbcode_tpl['email']; + } + + $text = preg_replace($patterns, $replacements, $text); + + return $text; + } + + /** + * Displays the credits + * + * @return void + * @since 1.5.5 + */ + public static function credits() + { + $ambit = JoomAmbit::getInstance(); +?> +
    +

    +
    + + Powered by JoomGallery + +

    + By: + + JoomGallery::ProjectTeam + +
    + get('version'); ?> +
    +getCategoryStructure(); + + // Get category and their parents + $pathCats = JoomHelper::getAllParentCategories($catid, $child, $all); + + $count = count($pathCats); + if(!$count) + { + return $path; + } + + // Construct the HTML + if($count == 1) + { + $category = reset($pathCats); + + // Link to category only if category published + if($linked && isset($allowed_categories[$catid])) + { + $path = ''.$category->name.''; + } + else + { + $path = $category->name; + } + } + else + { + // Reindex the array with index from 0 to n + $pathCatsidx = array_values($pathCats); + + // First element + if($linked && isset($allowed_categories[$pathCatsidx[0]->cid])) + { + $path = ''.$pathCatsidx[0]->name.''; + } + else + { + $path = $pathCatsidx[0]->name; + } + + for($i = 1; $i < $count; $i++) + { + if($linked && isset($allowed_categories[$pathCatsidx[$i]->cid])) + { + $path .= $separator.''.$pathCatsidx[$i]->name.''; + } + else + { + $path .= $separator.$pathCatsidx[$i]->name; + } + } + } + + if($with_home) + { + $home = ''.JText::_('COM_JOOMGALLERY_COMMON_HOME').''; + $path = $home.$separator.$path.' '; + } + + // Store it for later use + $catPaths[$catid] = $path; + + return $path; + } + + /** + * Creates the HTML output to display a minithumb for an image + * + * @param object $img Image object holding the image data + * @param string $class CSS class name for minithumb styling + * @param boolean $linkattribs Link attributes for creating a link on the minithumb, if false no link will created + * @param boolean $showtip Shows the thumbnail as tip on hoovering above minithumb + * @return string The HTML output + * @since 1.5.7 + */ + public static function minithumbimg($img, $class = null, $linkattribs = null, $showtip = true) + { + jimport('joomla.filesystem.file'); + + $ambit = JoomAmbit::getInstance(); + $config = JoomConfig::getInstance(); + $html = ''; + $linked = $linkattribs ? true : false; + + $thumb = $ambit->getImg('thumb_path', $img); + if(JFile::exists($thumb)) + { + $isSite = JFactory::getApplication()->isSite(); + $imginfo = getimagesize($thumb); + $url = $ambit->getImg('thumb_url', $img); + + if($showtip) + { + if($isSite) + { + $html .= '', null, true, false).'>'; + } + else + { + $html .= '', ENT_QUOTES, 'UTF-8').'">'; + } + } + if($linked) + { + if($isSite) + { + // Set the title attribute in a tag with title and/or + // description of image if a box is activated + if(!is_numeric($config->get('jg_detailpic_open')) || $config->get('jg_detailpic_open') > 1) + { + $atagtitle = JHtml::_('joomgallery.getTitleforATag', $img); + } + else + { + // Set the imgtitle by default + $atagtitle = 'title="'.$img->imgtitle.'"'; + } + $html .= ''; + } + else + { + $html .= ''; + } + } + $html .= ''.htmlspecialchars($img->imgtitle, ENT_QUOTES, 'UTF-8').'thumbnail) && !empty($cat->thumbnail)) + { + $thumb = $ambit->getImg('thumb_path', $cat->thumbnail, null, $cat->cid); + + jimport('joomla.filesystem.file'); + if(JFile::exists($thumb)) + { + $isSite = JFactory::getApplication()->isSite(); + $imginfo = getimagesize($thumb); + $url = $ambit->getImg('thumb_url', $cat->thumbnail, null, $cat->cid); + + // Clean category name + $catname = str_replace(' ', '', $cat->name); + $catname = trim(str_replace('»', '', $catname)); + + if($showtip) + { + if($isSite) + { + $html .= '', null, true, false).'>'; + } + else + { + $html .= '', ENT_QUOTES, 'UTF-8').'">'; + } + } + if($linked) + { + if($isSite) + { + $html .= ''; + } + else + { + $html .= ''; + } + } + $html .= ''.htmlspecialchars($catname, ENT_QUOTES, 'UTF-8').''; + } + + /** + * State buttons for approved/not yet approved/rejected state of images + * + * @param array $states Array of state information + * @param int $value Current state of the image + * @param int $i Number of the image in the current list + * @param string $prefix Optional prefix for task name + * @param boolean $enabled Indicates whether the buttons should be active + * @param int $id ID of the image + * @param int $owner ID of the owner of the image + * @param boolean $translate Indicates whether the state names should be translated + * @param string $checkbox Name prefix of the checkboxes in the current image list + * @return string HTML of the state buttons + * @since 3.1 + */ + public static function approved($states, $value, $i, $prefix = '', $enabled = true, $id = 0, $owner = 0, $translate = true, $checkbox = 'cb') + { + $state = JArrayHelper::getValue($states, (int) $value, $states[0]); + $task = array_key_exists('task', $state) ? $state['task'] : $state[0]; + $text = array_key_exists('text', $state) ? $state['text'] : (array_key_exists(1, $state) ? $state[1] : ''); + $active_title = array_key_exists('active_title', $state) ? $state['active_title'] : (array_key_exists(2, $state) ? $state[2] : ''); + $inactive_title = array_key_exists('inactive_title', $state) ? $state['inactive_title'] : (array_key_exists(3, $state) ? $state[3] : ''); + $tip = array_key_exists('tip', $state) ? $state['tip'] : (array_key_exists(4, $state) ? $state[4] : false); + $active_class = array_key_exists('active_class', $state) ? $state['active_class'] : (array_key_exists(5, $state) ? $state[5] : ''); + $inactive_class = array_key_exists('inactive_class', $state) ? $state['inactive_class'] : (array_key_exists(6, $state) ? $state[6] : ''); + + if($enabled) + { + // Button group is only necessary for 'not yet approved' + if($value == 0) + { + $html[] = ''; + } + + // Normal button for approving is necessary for states 'not yet approved' and 'rejected' + if($value == 0 || $value == -1) + { + $html[] = ''; + $html[] = ''; + $html[] = ''; + $html[] = ''; + } + + // Special rejecting button is necessary for states 'not yet approved' and 'approved' + if($value == 0 || $value == 1) + { + if($owner) + { + $owner = htmlspecialchars(JHtml::_('joomgallery.displayname', $owner), ENT_COMPAT, 'UTF-8'); + } + else + { + $owner = ''; + } + + JHtml::_('bootstrap.modal', 'jg-reject-popup'); + $html[] = ''; + + if($value == 0) + { + $html[] = ''; + } + else + { + $html[] = ''; + } + + $html[] = ''; + $html[] = ''; + + if($value == 0) + { + $html[] = ''; + } + + $html[] = ''; + } + } + else + { + // Disabled button (usually used if the user doesn't have the permission to change the state) + $html[] = ''; + $html[] = ''; + $html[] = ''; + } + + return implode($html); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/helpers/html/joomselect.php b/deployed/joomgallery/administrator/components/com_joomgallery/helpers/html/joomselect.php new file mode 100644 index 00000000..ec7060ac --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/helpers/html/joomselect.php @@ -0,0 +1,408 @@ +get('jg_ajaxcategoryselection')) + { + $app = JFactory::getApplication(); + + if(!$idtag) + { + $idtag = $cname; + } + + if($currentcat == 1) + { + $name = '-'; + } + else + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('name') + ->from(_JOOM_TABLE_CATEGORIES) + ->where('cid = '.(int) $currentcat); + $db->setQuery($query); + $name = $db->loadResult(); + } + + $matches = array(); + $onchange = ''; + if(preg_match('/onchange="(.*)"/', $attribs, $matches)) + { + $onchange = $matches[1]; + $attribs = trim(str_replace($matches[0], '', $attribs)); + } + $attribs = preg_replace('/size="(.*)"/', '', $attribs); + + JText::script('COM_JOOMGALLERY_COMMON_REQUEST_ERROR'); + JText::script('COM_JOOMGALLERY_COMMON_CATEGORIES_NO_RESULTS'); + + JHtml::_('behavior.framework', true); + $doc = JFactory::getDocument(); + if($app->isSite()) + { + $url = JRoute::_('index.php?option='._JOOM_OPTION.'&task=categories.getcategories', false); + $doc->addStyleSheet(JoomAmbit::getInstance()->getStyleSheet('joomgallery.css')); + } + else + { + + $url = JRoute::_('index.php?option='._JOOM_OPTION.'&controller=categories&task=getcategories', false); + $doc->addStyleSheet(JoomAmbit::getInstance()->getStyleSheet('admin.joomgallery.css')); + } + $doc->addScript(JoomAmbit::getInstance()->getScript('categories.js')); + $jscript = ' + '; + + return $jscript . ' + + + '; + } + + $user = JFactory::getUser(); + $ambit = JoomAmbit::getInstance(); + $cats = $ambit->getCategoryStructure(true); + $options = array(); + //$filter = ($cname == 'parent_id' && $orig != null) ? true : false; + $origfound = false; + $filtercatkeys = array(); + + $paths = array(); + + $action2 = false; + if($action == 'joom.upload') + { + $action2 = 'joom.upload.inown'; + } + if($action == 'core.create') + { + $action2 = 'joom.create.inown'; + } + if($action == 'core.edit') + { + $action2 = 'core.edit.own'; + } + + foreach($cats as $key => $cat) + { + // Avoid 'ROOT' entry in drop down list in the case that no category has been created yet + if($cat->cid === 0) + { + continue; + } + + // Check whether a certain category and it's sub-categories + // have to be filtered out of the list + if($orig) + { + if(!$origfound) + { + if($cat->cid == $orig) + { + $origfound = true; + $filtercatkeys[$orig] = true; + } + } + else + { + if(isset($filtercatkeys[$cat->parent_id])) + { + $filtercatkeys[$key] = true; + } + } + } + + if($cat->parent_id > 1) + { + //$paths[$key] = $paths[$cat->parent_id].$separator.$cat->name; + $paths[$key] = $paths[$cat->parent_id] + 1; + } + else + { + $paths[$key] = 0; + } + + if( $task == 'filter' + || $key == $currentcat + || ( !isset($filtercatkeys[$key]) + && ( $user->authorise($action, _JOOM_OPTION.'.category.'.$key) + || ( $action2 + && $cat->owner == $user->get('id') + && $user->authorise($action2, _JOOM_OPTION.'.category.'.$cat->cid) + ) + ) + ) + ) + { + // Build select option for that category + $options[$key] = new stdClass(); + $options[$key]->cid = $cat->cid; + $options[$key]->path = str_repeat($separator, $paths[$key]).$cat->name; + } + } + + if($task == 'filter' || $currentcat == 0 || ($action == 'core.create' && $user->authorise($action, _JOOM_OPTION))) + { + $rootcat = new stdClass(); + $rootcat->cid = ''; + $rootcat->path = ($task == 'filter') ? JText::_('COM_JOOMGALLERY_COMMON_ALL') : ''; + array_unshift($options, $rootcat); + } + + $count = count($options); + if(!$count || ($count == 1 && !reset($options)->cid)) + { + // Return a hidden field in order to avoid JavaScript errors + return ' + '; + } + + // Sort the array with key pathname if more than one element + if($count > 1) + { + //usort($options, array('JHTMLJoomSelect', 'sortCatArray')); + } + + $output = JHTML::_('select.genericlist', $options, $cname, $attribs, 'cid', 'path', $currentcat, $idtag); + + return $output; + } + + /** + * Construct HTML list of users + * + * @param string $name Name of the HTML select list to use + * @param array $active Array of selected users + * @param boolean $nouser True, if 'No user' should be included on top of the list + * @param array $additional Additional entries to add + * @param string $javascript Additional code in the select list + * @param int $multiple Size of the box if it shall be a multiple select box, 0 otherwise + * @param mixed $idtag String to use as id tag for the select box + * @return string The HTML output + * @since 1.5.5 + */ + public static function users($name, $active, $nouser = false, $additional = array(), $javascript = null, $multiple = 6, $idtag = false) + { + static $users = null; + + $config = JoomConfig::getInstance(); + + if(is_null($users)) + { + $db = JFactory::getDbo(); + + $type = $config->get('jg_realname') ? 'name' : 'username'; + + $query = $db->getQuery(true) + ->select('COUNT(id)') + ->from('#__users') + ->where('block = 0'); + $db->setQuery($query); + + self::$count = $db->loadResult(); + + if(self::$count <= $config->get('jg_use_listbox_max_user_count') || !$multiple) + { + $users = array(); + + $query->clear() + ->select('id AS value') + ->select($type.' AS text') + ->from('#__users') + ->where('block = 0') + ->order($type.' ASC'); + $db->setQuery($query); + + $users = $db->loadObjectList(); + } + } + + if(self::$count > $config->get('jg_use_listbox_max_user_count') && $multiple) + { + return ''; + } + + $options = array(); + + foreach($additional as $key => $value) + { + $options[] = JHtml::_('select.option', $key, $value); + } + + if($nouser) + { + if(JFactory::getApplication()->isSite()) + { + $options[] = JHtml::_('select.option', '0', JText::_('COM_JOOMGALLERY_DETAIL_NAMETAGS_SELECT_USER')); + } + else + { + $options[] = JHtml::_('select.option', '0', JText::_('COM_JOOMGALLERY_COMMON_NO_USER')); + } + } + + $options = array_merge($options, $users); + + $multiple_box = ''; + if($multiple > 1) + { + $multiple_box = ' multiple="multiple" size="'.$multiple.'"'; + } + + if($javascript) + { + $javascript = ' onchange="'.$javascript.'"'; + } + + return JHtml::_('select.genericlist', $options, $name, 'class="inputbox"'.$multiple_box.$javascript, 'value', 'text', $active, $idtag); + } + + /** + * Callback function for sorting an array of objects to assembled names of + * categories with alle parent categories + * + * @param object $a Element one + * @param object $b Element two + * @return int 0 if names equal, -1 if a < b, 1 if a > b + * @since 1.0.0 + */ + public static function sortCatArray($a, $b) + { + return strcmp($a->path, $b->path); + } + + /** + * Creates a HMTL select list of OpenImage options + * + * @param string $name Name of the field + * @param string $selected Option that should be preselected. + * @param boolean $detail True, if the default detail view shall be an available option, defaults to true + * @param boolean $default True, if the 'like in JoomGallery configured' shall be an available option, defaults to false + * @param string $lang_prefix Prefix for the language constants of the options, defaults to 'COM_JOOMGALLERY_CONFIG_CV_GS_OPEN' + * @param string $attr Optional attributes for the HTML element + * @param array $extra Array of additional options for the select list + * @return string The HTML select list of OpenImage options + * @since 3.0 + */ + public static function openImage($name, $selected = null, $detail = true, $default = false, $lang_prefix = 'COM_JOOMGALLERY_CONFIG_CV_GS_OPEN_', $attr = null, $extra = array()) + { + // Additional options are placed first in the list + $options = $extra; + + if($default) + { + $options[] = JHtml::_('select.option', 'default', JText::_($lang_prefix.'LIKE_IN_JOOMGALLERY')); + } + + if($detail) + { + $options[] = JHtml::_('select.option', '0', JText::_($lang_prefix.'DEFAULT')); + } + + $options[] = JHtml::_('select.option', '1', JText::_($lang_prefix.'BLANK_WINDOW')); + $options[] = JHtml::_('select.option', '2', JText::_($lang_prefix.'JS_WINDOW')); + $options[] = JHtml::_('select.option', '3', JText::_($lang_prefix.'DHTML')); + #$options[] = JHtml::_('select.option', '4', JText::_('COM_JOOMGALLERY_MODAL')); + $options[] = JHtml::_('select.option', '5', JText::_($lang_prefix.'THICKBOX3')); + $options[] = JHtml::_('select.option', '6', JText::_($lang_prefix.'SLIMBOX')); + + // Load plugins in order to search for additional OpenImage plugins + JPluginHelper::importPlugin('joomgallery'); + $plugins = JDispatcher::getInstance()->trigger('onJoomOpenImageGetName'); + + foreach($plugins as $plugin) + { + $options[] = JHtml::_('select.option', $plugin); + } + + if(!$attr) + { + $attr = 'class="inputbox" size="'.count($options).'"'; + } + + return JHtml::_('select.genericlist', $options, $name, $attr, 'value', 'text', $selected); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/helpers/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/helpers/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/helpers/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/helpers/migration.php b/deployed/joomgallery/administrator/components/com_joomgallery/helpers/migration.php new file mode 100644 index 00000000..d5e6073d --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/helpers/migration.php @@ -0,0 +1,2161 @@ +_mainframe = JFactory::getApplication(); + $this->_db = JFactory::getDbo(); + $this->_config = JoomConfig::getInstance(); + $this->_ambit = JoomAmbit::getInstance(); + + $this->logfilename = 'migration.'.$this->migration.'.php'; + + require_once JPATH_COMPONENT.'/helpers/refresher.php'; + + $this->refresher = new JoomRefresher(array('task' => 'migrate&migration='.$this->migration)); + + JLog::addLogger(array('text_file' => $this->logfilename, 'text_entry_format' => '{DATETIME} {PRIORITY} {MESSAGE}'), JLog::ALL, array('migration'.$this->migration)); + + $this->newCatid = $this->_mainframe->getUserState('joom.migration.internal.new_catid', 1); + + $this->copyImages = $this->getStateFromRequest('copy_images', 'copy_images', $this->copyImages, 'boolean'); + $this->checkOwner = $this->getStateFromRequest('check_owner', 'check_owner', $this->checkOwner, 'boolean'); + + $this->isCli = $this->getStateFromRequest('is_cli', 'is_cli', $this->isCli, 'boolean'); + + // Connect to second database if necessary + $db = $this->getStateFromRequest('db2', 'db', array(), 'array'); + if(JArrayHelper::getValue($db, 'enabled', false, 'boolean')) + { + $driver = JArrayHelper::getValue($db, 'db_type', 'mysqli', 'string'); + $host = JArrayHelper::getValue($db, 'db_host', 'localhost', 'string'); + $name = JArrayHelper::getValue($db, 'db_name', '', 'string'); + $user = JArrayHelper::getValue($db, 'db_user', '', 'string'); + $password = JArrayHelper::getValue($db, 'db_pass', '', 'string'); + $prefix = $this->getStateFromRequest('prefix', 'prefix', '', 'cmd'); + if(!$prefix) + { + $prefix = JArrayHelper::getValue($db, 'prefix', '', 'cmd'); + $this->setState('prefix', $prefix); + } + + $options = array ('driver' => $driver, 'host' => $host, 'user' => $user, 'password' => $password, 'database' => $name, 'prefix' => $prefix); + + $this->_db2 = JDatabaseDriver::getInstance($options); + + $this->otherDatabase = true; + } + else + { + $this->_db2 = $this->_db; + } + } + + /** + * Opens the log file and puts first comments into it. + * + * @return boolean True on success, false if errors occurred. + * @since 1.5.0 + */ + public function start() + { + $this->_mainframe->setUserState('joom.migration.internal', null); + $this->writeLogfile('Migration Step started'); + $this->writeLogfile('max. execution time: '.@ini_get('max_execution_time').' seconds'); + $this->writeLogfile('calculated refresh time: '.$this->refresher->getMaxTime().' seconds'); + $this->writeLogfile('*****************************'); + + try + { + $this->doMigration(); + } + catch(Exception $e) + { + $this->setError($e->getMessage()); + } + + return $this->end(); + } + + /** + * Continues the migration + * + * @return boolean True on success, false if errors occurred. + * since 2.0 + */ + public function migrate() + { + $this->writeLogfile('*****************************'); + $this->writeLogfile('Migration Step started'); + + try + { + $this->doMigration(); + } + catch(Exception $e) + { + $this->setError($e->getMessage()); + } + + return $this->end(); + } + + /** + * Checks the remaining time of the current migration step + * + * @return boolean True: Time remaining for migration, false: No more time left + * @since 1.5.0 + */ + protected function checkTime() + { + return $this->refresher->check(); + } + + /** + * Make a redirect to continue/end migration + * + * @param string $task Name of the task to continue with after the refresh + * @return void + * @since 1.5.0 + */ + protected function refresh($task = null) + { + $this->_mainframe->setUserState('joom.migration.internal.task', $task); + + if($this->isCli) + { + // If executed from the command line it is not necessary to refresh + return; + } + + $this->writeLogfile('Refresh to continue the migration'); + $this->refresher->refresh(); + } + + /** + * Puts last comments into the log file, + * closes it and sets redirect with report of success. + * + * @return boolean True on success, false if errors occurred. + * @since 1.5.0 + */ + protected function end() + { + $this->writeLogfile('end of migration - exiting'); + $this->writeLogfile('*****************************'); + + $msgType = 'message'; + $success = true; + $errors = $this->_mainframe->getUserState('joom.migration.internal.errors'); + if($errors) + { + $this->writeLogfile('Errors recognized: '.$errors); + $msg = 'There were '.$errors.' error(s) during migration. Please have a look at the log file.'; + $msgType = 'error'; + $success = false; + } + else + { + $msg = 'Migration successfully ended'; + } + + $this->writeLogfile('Migration ended'); + + if(!$this->isCli) + { + // Refreshing is only necessary if not executed from the command line + $this->refresher->refresh(null, 'display', $msg, $msgType); + } + + return $success; + } + + /** + * Writes a line into the logfile + * + * @param string $line The line to write into the logfile + * @param int $priority Determines whether the line is an info or an error message + * @return void + * @since 1.5.0 + */ + protected function writeLogfile($line, $priority = JLog::INFO) + { + JLog::add($line, $priority, 'migration'.$this->migration); + } + + /** + * Increases the error counter and optionally appends an error message + * + * @param string $msg An optional error message to write into the logfile + * @param boolean $db True, if a DB-Error occured + * @return void + * @since 1.5.0 + */ + protected function setError($msg = null, $db = false) + { + $error_counter = $this->_mainframe->getUserState('joom.migration.internal.errors'); + if(is_null($error_counter)) + { + $error_counter = 1; + } + else + { + $error_counter++; + } + + $this->_mainframe->setUserState('joom.migration.internal.errors', $error_counter); + + if(!is_null($msg)) + { + if(!$db) + { + $this->writeLogfile('Error: '.$msg, JLog::ERROR); + } + else + { + $replace = array("\r\n", "\r", "\n", ' '); + $msg = str_replace($replace, ' ', $msg); + $this->writeLogfile('DB error: '.$msg, JLog::ERROR); + } + } + } + + /** + * Returns the current task of the migration. + * + * Please use this function and @see setTask(string) for managing different steps during the migration + * + * @param string $default The default task to return if there isn't any task stored in the session + * @return The current task of the migration + * @since 3.1 + */ + protected function getTask($default = null) + { + return $this->_mainframe->getUserState('joom.migration.internal.task', $default); + } + + /** + * Sets the current task of the migration in the session. + * + * Please use this function and @see getTask() for managing different steps during the migration + * + * @param string $task The task name to set + * @return The previous task if one existed + * @since 3.1 + */ + protected function setTask($task) + { + return $this->_mainframe->setUserState('joom.migration.internal.task', $task); + } + + /** + * Returns a custom state stored in the session + * + * Please use this function and @see setState(string, mixed) for storing different states across site refreshes + * + * @param string $key Name of the state to retrieve + * @param mixed $default The default state to return if it isn't stored in the session + * @return The requested state + * @since 3.1 + */ + protected function getState($key, $default = null) + { + return $this->_mainframe->getUserState('joom.migration.data.'.$this->migration.'.'.$key, $default); + } + + /** + * Sets a custom state in the session. + * + * Please use this function and @see getState(string, mixed) for storing different states across site refreshes + * + * @param string $key Name of the state to set + * @param mixed $task The state to set + * @return The previous state if one existed + * @since 3.1 + */ + protected function setState($key, $state) + { + return $this->_mainframe->setUserState('joom.migration.data.'.$this->migration.'.'.$key, $state); + } + + /** + * Gets the value of a state, first looking in the request for it + * + * Please use this function, @see getState(string, mixed) and @see setState(string, mixed) for storing different states across site refreshes + * + * @param string $key The name of the state + * @param string $request The name of the variable passed in a request + * @param string $default The default value for the variable if not found + * @param string $type Filter for the variable, for valid values see {@link JFilterInput::clean()} + * @return The requested state + * @since 3.1 + */ + public function getStateFromRequest($key, $request, $default = null, $type = 'none') + { + $cur_state = $this->getState($key, $default); + $new_state = $this->_mainframe->input->get($request, null, $type); + + // Save the new value only if it was set in this request + if($new_state !== null) + { + $this->setState($key, $new_state); + } + else + { + $new_state = $cur_state; + } + + return $new_state; + } + + /** + * Renders the form for configuring a migration using an XML file + * which has the same name than the migration script + * + * @return string HTML of the rendered form + * @since 3.1 + */ + public function getForm() + { + // Try to load language file of the migration script + JFactory::getLanguage()->load('com_joomgallery.migrate'.$this->migration); + + // Prepare display data + $displayData = new stdClass(); + $displayData->url = JRoute::_('index.php?option='._JOOM_OPTION.'&controller=migration&task=check'); + $displayData->migration = $this->migration; + $displayData->fields = array(); + $displayData->description = ''; + + JForm::addFormPath(JPATH_COMPONENT.'/helpers/migration/'); + JForm::addFormPath(JPATH_COMPONENT.'/models/forms'); + JForm::addFieldPath(JPATH_COMPONENT.'/models/fields'); + + // Try to load additional form fields + try + { + $form = JForm::getInstance(_JOOM_OPTION.'.migrate.'.$this->migration, 'migrate'.$this->migration); + + // Check for form field with name 'database' which means that fields for + // the connection to a second database should be displayed + $form->setFieldAttribute('database', 'id', 'database_'.$this->migration); + if($databaseField = $form->getField('database')) + { + // Render the field now because it adds other form fields to the form + // which has to happen afore all the fields are retrieved for displaying + $databaseField->input; + } + + $data = $this->_mainframe->getUserState('joom.migration.data.'.$this->migration, new stdClass()); + $data->check_owner = (int) $this->checkOwner; + $data->copy_images = (int) $this->copyImages; + $data->database = $this->otherDatabase; + $data->db = array(); + $db = (array) $this->getState('db2', array()); + $data->db['enabled'] = $data->database; + $data->db['db_type'] = JArrayHelper::getValue($db, 'db_type', 'mysqli', 'string'); + $data->db['db_host'] = JArrayHelper::getValue($db, 'db_host', 'localhost', 'string'); + $data->db['db_user'] = JArrayHelper::getValue($db, 'db_user', '', 'string'); + $data->db['db_pass'] = JArrayHelper::getValue($db, 'db_pass', '', 'string'); + $data->db['db_name'] = JArrayHelper::getValue($db, 'db_name', '', 'string'); + $data->db['prefix'] = $this->getState('prefix'); + $form->bind($data); + + $displayData->fields = $form->getGroup(''); + if(count($fieldsets = $form->getFieldsets()) && isset(reset($fieldsets)->description)) + { + $displayData->description = JText::_(reset($fieldsets)->description); + } + } + catch(Exception $e) + { + // Simply don't add any fields if there is no valid form + } + + // Render the form + $layout = new JLayoutFile('joomgallery.migration.form', JPATH_COMPONENT.'/layouts'); + + return $layout->render($displayData); + } + + /** + * Checks general requirements for migration + * + * @param string $xml_dile Path to the XML-File of the required extension + * @param string $min_version minimal required version, false if no check shall be performed + * @param string $min_version maximum possible version, false if no check shall be performed + * @return string Message about state or boolean true or false. + * @since 1.5.0 + */ + protected function checkGeneral($xml_file = null, $min_version = false, $max_version = false) + { + // Check extension + if($xml_file) + { + if(!file_exists($xml_file)) + { + return JText::_('COM_JOOMGALLERY_MIGMAN_EXTENSION_NOT_INSTALLED'); + } + else + { + if($min_version || $max_version) + { + $xml = simplexml_load_file($xml_file); + + if(isset($xml->version)) + { + $version = (string) $xml->version; + if($min_version) + { + $comparision_min = version_compare($version, $min_version, '>='); + } + else + { + $comparision_min = true; + } + if($max_version) + { + $comparision_max = version_compare($version, $max_version, '<='); + } + else + { + $comparision_max = true; + } + if(!$comparision_min || !$comparision_max) + { + return JText::_('COM_JOOMGALLERY_MIGMAN_WRONG_VERSION'); + } + } + } + } + } + + // Check whether site is offline + $sitestatus = $this->_mainframe->getCfg('offline'); + $displayData = new stdClass(); + $displayData->title = JText::_('COM_JOOMGALLERY_MIGMAN_SITESTATUS'); + $displayData->checks = array(); + $displayData->checks[] = array('title' => JText::_('COM_JOOMGALLERY_MIGMAN_SITE_OFFLINE'), 'state' => $sitestatus == 1); + + $layout = new JLayoutFile('joomgallery.migration.checksection', JPATH_COMPONENT.'/layouts'); + echo $layout->render($displayData); + + return $sitestatus == 1; + } + + /** + * Checks required directories for migration + * + * @param array $dirs Array of directories to search for + * @return boolean True if all directories are existent, false otherwise + * @since 1.5.0 + */ + protected function checkDirectories($dirs = array()) + { + // Add JoomGallery directories + $joom_dirs = array($this->_ambit->get('img_path'), + $this->_ambit->get('orig_path'), + $this->_ambit->get('thumb_path')); + $dirs = array_merge($dirs, $joom_dirs); + $ready = true; + $displayData = new stdClass; + $displayData->title = JText::_('COM_JOOMGALLERY_MIGMAN_DIRECTORIES'); + $displayData->checks = array(); + foreach($dirs as $dir) + { + $directory = array(); + $directory['title'] = $dir; + $directory['state'] = true; + if(!is_dir($dir)) + { + $ready = false; + $directory['state'] = false; + } + + $displayData->checks[] = $directory; + } + + // Check log directory and log file + $log_dir = JPath::clean($this->_mainframe->getCfg('log_path')); + $check = array('title' => JText::sprintf('COM_JOOMGALLERY_MIGMAN_LOG_DIRECTORY', $log_dir)); + $error = false; + $message = ''; + if(is_dir($log_dir)) + { + $log_file = JPath::clean($log_dir.'/'.$this->logfilename); + if(is_file($log_file)) + { + if(is_writable($log_file)) + { + $message = JText::sprintf('COM_JOOMGALLERY_MIGMAN_LOG_FILE_IS_WRITABLE', $this->logfilename); + } + else + { + $error = true; + $message = JText::sprintf('COM_JOOMGALLERY_MIGMAN_LOG_FILE_IS_NOT_WRITABLE', $this->logfilename); + } + } + else + { + if(is_writable($log_dir)) + { + $message = JText::sprintf('COM_JOOMGALLERY_MIGMAN_LOG_FILE_WILL_BE_CREATED', $this->logfilename); + } + else + { + $error = true; + $message = JText::_('COM_JOOMGALLERY_MIGMAN_LOG_FILE_IS_NOT_WRITABLE'); + } + } + } + else + { + $error = true; + } + + if($error && $message) + { + $check['title'] .= ' '.$message.''; + } + else + { + if(!$error) + { + $check['title'] .= ' '.$message.''; + } + } + + $check['state'] = !$error; + $displayData->checks[] = $check; + + $layout = new JLayoutFile('joomgallery.migration.checksection', JPATH_COMPONENT.'/layouts'); + echo $layout->render($displayData); + + return $ready && !$error; + } + + /** + * Checks required database tables for migration + * + * @param array $tables Array of database tables to search for + * @return boolean True if all tables are existent, false otherwise + * @since 1.5.0 + */ + protected function checkTables($tables = array()) + { + $displayData = new stdClass(); + $displayData->title = JText::_('COM_JOOMGALLERY_MIGMAN_DATABASETABLES'); + + $ready = false; + + if(!$this->otherDatabase || is_null($this->_db2)) + { + $db = $this->_db; + } + else + { + $db = $this->_db2; + } + + $displayData->checks = array(); + foreach($tables as $table) + { + $check = array(); + + try + { + $query = $db->getQuery(true) + ->select('COUNT(*)') + ->from($table); + $db->setQuery($query); + + $count = $db->loadResult(); + + if($count == 0) + { + $check['title'] = $table.': '.JText::_('COM_JOOMGALLERY_MIGMAN_EMPTY').''; + $check['state'] = true; + } + else + { + $check['title'] = $table.': '.$count .' '.JText::_('COM_JOOMGALLERY_MIGMAN_ROWS').''; + $check['state'] = true; + $ready = true; + } + } + catch(Exception $e) + { + $check['title'] = $table.': '.$db->getErrorMsg().''; + $check['state'] = false; + } + + $displayData->checks[] = $check; + } + + // Check JoomGallery tables + $tables = array(_JOOM_TABLE_IMAGES, + _JOOM_TABLE_CATEGORIES, + _JOOM_TABLE_COMMENTS, + _JOOM_TABLE_NAMESHIELDS, + _JOOM_TABLE_USERS, + _JOOM_TABLE_VOTES, + _JOOM_TABLE_IMAGE_DETAILS, + _JOOM_TABLE_CATEGORY_DETAILS); + $prefix = $this->_mainframe->getCfg('dbprefix'); + foreach($tables as $table) + { + $check = array(); + if($table != _JOOM_TABLE_CATEGORIES) + { + $query = $this->_db->getQuery(true) + ->select('COUNT(*)') + ->from($this->_db->qn($table)); + } + else + { + $query =$this->_db->getQuery(true) + ->select('COUNT(*)') + ->from($this->_db->qn(_JOOM_TABLE_CATEGORIES)) + ->where('cid != 1'); + } + $this->_db->setQuery($query); + $count = $this->_db->loadResult(); + if(!is_null($count) && $count == 0) + { + $check['title'] = str_replace('#__', $prefix, $table).': '.JText::_('COM_JOOMGALLERY_MIGMAN_EMPTY').''; + $check['state'] = true; + } + else + { + $check['title'] = str_replace('#__', $prefix, $table).': '.$count .' '.JText::_('COM_JOOMGALLERY_MIGMAN_ROWS').'. '; + $check['title'] .= JText::_('COM_JOOMGALLERY_MIGMAN_ONLY_IN_NEW_INSTALLATION').' '.JText::_('COM_JOOMGALLERY_MIGMAN_PLEASE_REINSTALL'); + $check['state'] = false; + $ready = false; + } + + $displayData->checks[] = $check; + } + + // Check whether ROOT category exists + $check = array(); + $query = $this->_db->getQuery(true) + ->select('COUNT(*)') + ->from($this->_db->qn(_JOOM_TABLE_CATEGORIES)) + ->where('cid = 1') + ->where('name = '.$this->_db->q('ROOT')) + ->where('parent_id = 0'); + $this->_db->setQuery($query); + if($this->_db->loadResult()) + { + $check['title'] = JText::_('COM_JOOMGALLERY_MIGMAN_ROOT_CATEGORY_EXISTS'); + $check['state'] = true; + } + else + { + $check['title'] = ''.JText::_('COM_JOOMGALLERY_MIGMAN_ROOT_CATEGORY_DOES_NOT_EXIST').' '.JText::_('COM_JOOMGALLERY_MIGMAN_PLEASE_REINSTALL'); + $check['state'] = false; + $ready = false; + } + + $displayData->checks[] = $check; + + // Check whether ROOT asset exists + $check = array(); + $query = $this->_db->getQuery(true) + ->select('COUNT(*)') + ->from($this->_db->qn('#__assets')) + ->where('name = '.$this->_db->q(_JOOM_OPTION)) + ->where('parent_id = 1'); + $this->_db->setQuery($query); + if($this->_db->loadResult()) + { + $check['title'] = JText::_('COM_JOOMGALLERY_MIGMAN_ROOT_ASSET_EXISTS'); + $check['state'] = true; + } + else + { + $check['title'] = ''.Text::_('COM_JOOMGALLERY_MIGMAN_ROOT_ASSET_DOES_NOT_EXIST').' '.JText::_('COM_JOOMGALLERY_MIGMAN_PLEASE_REINSTALL'); + $check['state'] = false; + $ready = false; + } + + $displayData->checks[] = $check; + + $layout = new JLayoutFile('joomgallery.migration.checksection', JPATH_COMPONENT.'/layouts'); + echo $layout->render($displayData); + + return $ready; + } + + /** + * Displays message whether migration can be started or not. + * If yes, the button which starts the migration will be displayed, too. + * + * @param boolean $ready True, if the migration may be started + * @return void + * @since 1.5.0 + */ + protected function endCheck($ready = false) + { + $displayData = new stdClass(); + $displayData->ready = $ready; + $displayData->url = JRoute::_('index.php?option='._JOOM_OPTION.'&controller=migration'); + $displayData->migration = $this->migration; + + $layout = new JLayoutFile('joomgallery.migration.checkend', JPATH_COMPONENT.'/layouts'); + echo $layout->render($displayData); + } + + /** + * Starts all default migration checks. + * + * If you want to add additional migration checks + * you will have to call all check functions above manually. + * Please don't forget to check whether they return 'true'. + * + * @param array $dirs Array of directories to search for + * @param array $tables Array of database tables to search for + * @param string $xml Path to the XML-File of the required extension + * @param string $min_version minimal required version, false if no check shall be performed + * @param string $min_version maximum possible version, false if no check shall be performed + * @return void + * @since 1.5.0 + */ + public function check($dirs = array(), $tables = array(), $xml = false, $min_version = false, $max_version = false) + { + // Check for correct connection to second database if necessary + if($this->otherDatabase) + { + try + { + $this->_db2->connect(); + } + catch(Exception $e) + { + $this->_mainframe->redirect('index.php?option='._JOOM_OPTION.'&controller=migration', $e->getMessage(), 'error'); + } + } + + $layout = new JLayoutFile('joomgallery.migration.checkstart', JPATH_COMPONENT.'/layouts'); + echo $layout->render(null); + + $ready = array(); + $ready[] = $this->checkGeneral($xml, $min_version, $max_version); + if($ready[0] !== true && $ready[0] !== false) + { + $this->_mainframe->redirect('index.php?option='._JOOM_OPTION.'&controller=migration', $ready[0], 'notice'); + } + $ready[] = $this->checkDirectories($dirs); + $ready[] = $this->checkTables($tables); + $this->endCheck(!in_array(false, $ready)); + } + + /** + * Main migration function + * + * @return void + * @since 1.5.0 + */ + abstract protected function doMigration(); + + /** + * Returns the maximum category ID of the extension to migrate from. + * + * This is necessary because in JoomGallery there can't be any category + * with ID 1, so we have to look for a new one. + * + * @return int The maximum category ID of the extension to migrate from + * @since 2.0 + */ + abstract protected function getMaxCategoryId(); + + /** + * Creates directories and the database entry for a category + * + * @param object $cat Holds information about the new category + * @param boolean $checkOwner Determines whether the owner ID shall be checked against the existing users + * @return boolean True on success, false otherwise + * @since 1.5.0 + */ + public function createCategory($cat, $checkOwner = null) + { + jimport('joomla.filesystem.file'); + + if(is_null($checkOwner)) + { + $checkOwner = $this->checkOwner; + } + + // Some checks + if(!isset($cat->cid)) + { + $this->setError('Invalid category ID'); + + return false; + } + if(!isset($cat->name)) + { + $cat->name = 'no cat name'; + } + if(!isset($cat->alias)) + { + // Will be created later on + $cat->alias = ''; + } + if(!isset($cat->parent_id) || $cat->parent_id < 0) + { + $cat->parent_id = 1; + } + else + { + // If category with parent category ID 1 comes in we have + // to set the parent ID to the newly created one because + // category with ID 1 is the ROOT category in JoomGallery + if($cat->parent_id == 1) + { + $cat->parent_id = $this->newCatid; + } + + // Main categories are children of the ROOT category + if($cat->parent_id == 0) + { + $cat->parent_id = 1; + } + } + if(!isset($cat->description)) + { + $cat->description = ''; + } + if(!isset($cat->ordering)) + { + $cat->ordering = 0; + } + if(!isset($cat->lft)) + { + $cat->lft = $cat->ordering; + } + if(!isset($cat->access)) + { + $cat->access = $this->_mainframe->getCfg('access'); + } + if(!isset($cat->published)) + { + $cat->published = 0; + } + if(!isset($cat->hidden)) + { + $cat->hidden = 0; + } + if(!isset($cat->in_hidden)) + { + $cat->in_hidden = 0; + } + if( !isset($cat->owner) + || !is_numeric($cat->owner) + || $cat->owner < 1 + || ($checkOwner && !JUser::getTable()->load($cat->owner)) + ) + { + $cat->owner = 0; + } + if(!isset($cat->password)) + { + $cat->password = ''; + } + if(!isset($cat->thumbnail)) + { + $cat->thumbnail = 0; + } + if(!isset($cat->img_position)) + { + $cat->img_position = 0; + } + if(!isset($cat->params)) + { + $cat->params = ''; + } + if(!isset($cat->metakey)) + { + $cat->metakey = ''; + } + if(!isset($cat->metadesc)) + { + $cat->metadesc = ''; + } + if(!isset($cat->exclude_toplists)) + { + $cat->exclude_toplists = 0; + } + if(!isset($cat->exclude_search)) + { + $cat->exclude_search = 0; + } + + $catid_changed = false; + if($cat->cid == 1) + { + // Special handling for categories with ID 1 because that's the ROOT category in JoomGallery + $cat->cid = $this->getMaxCategoryId() + 1; + + // Store the new category ID because we have to use it for the images and categories in this category + $this->newCatid = $cat->cid; + $this->_mainframe->setUserState('joom.migration.internal.new_catid', $this->newCatid); + + $this->writeLogfile('New ID '.$cat->cid.' assigned to category '.$cat->name); + + $catid_changed = true; + } + + // Make the category name safe + JFilterOutput::objectHTMLSafe($cat->name); + + // If the new category should be assigned as subcategory... + if($cat->parent_id > 1) + { + // Save the category path of parent category in a variable + $parentpath = JoomHelper::getCatPath($cat->parent_id); + } + else + { + // Otherwise leave it empty + $parentpath = ''; + } + + // Creation of category path + // Cleaning of category title with function JoomFile::fixFilename + // so special chars are converted and underscore removed + // affects only the category path + $newcatname = JoomFile::fixFilename($cat->name); + // Add an underscore and the category ID + // affects only the category path + $newcatname = $newcatname.'_'.$cat->cid; + // Prepend - if exists - the parent category path + $cat->catpath = $parentpath.$newcatname; + + // Create the paths of category for originals, pictures, thumbnails + $cat_originalpath = JPath::clean($this->_ambit->get('orig_path').$cat->catpath); + $cat_detailpath = JPath::clean($this->_ambit->get('img_path').$cat->catpath); + $cat_thumbnailpath = JPath::clean($this->_ambit->get('thumb_path').$cat->catpath); + + $result = array(); + if(!JFolder::exists($cat_originalpath)) + { + $result[] = JFolder::create($cat_originalpath); + $result[] = JoomFile::copyIndexHtml($cat_originalpath); + } + if(!JFolder::exists($cat_detailpath)) + { + $result[] = JFolder::create($cat_detailpath); + $result[] = JoomFile::copyIndexHtml($cat_detailpath); + } + if(!JFolder::exists($cat_thumbnailpath)) + { + $result[] = JFolder::create($cat_thumbnailpath); + $result[] = JoomFile::copyIndexHtml($cat_thumbnailpath); + } + + // Create database entry + $query = $this->_db->getQuery(true) + ->insert(_JOOM_TABLE_CATEGORIES) + ->columns('cid, name, alias, parent_id, lft, description, access, published, hidden, in_hidden, password, owner, thumbnail, img_position, catpath, params, metakey, metadesc, exclude_toplists, exclude_search') + ->values( (int) $cat->cid.','. + $this->_db->quote($cat->name).','. + $this->_db->quote($cat->alias).','. + (int) $cat->parent_id.','. + (int) $cat->lft.','. + $this->_db->quote($cat->description).','. + (int) $cat->access.','. + (int) $cat->published.','. + (int) $cat->hidden.','. + (int) $cat->in_hidden.','. + $this->_db->quote($cat->password).','. + (int) $cat->owner.','. + (int) $cat->thumbnail.','. + (int) $cat->img_position.','. + $this->_db->quote($cat->catpath).','. + $this->_db->quote($cat->params).','. + $this->_db->quote($cat->metakey).','. + $this->_db->quote($cat->metadesc).','. + (int) $cat->exclude_toplists.','. + (int) $cat->exclude_toplists + ); + + $this->_db->setQuery($query); + $result[] = $this->runQuery(); + + // Create asset and alias + $table = JTable::getInstance('joomgallerycategories', 'Table'); + $table->load($cat->cid); + if($table->check()) + { + $result['db'] = $table->store(); + if(!$result['db']) + { + $this->setError($table->getError(), true); + } + } + + if($catid_changed) + { + // Set back category ID in the object because it may be used again later + $cat->cid = 1; + } + + if(!in_array(false, $result)) + { + $this->writeLogfile('Category '.($catid_changed ? $this->newCatid : $cat->cid).' created: '.$cat->name); + + return true; + } + else + { + $this->writeLogfile(' -> Error creating category '.($catid_changed ? $this->newCatid : $cat->cid).': '.$cat->name); + + return false; + } + } + + /** + * Runs a query set afore and handles the errors + * + * @param string The database method to use + * @return mixed The result of the query + * @since 2.0 + */ + protected function runQuery($method = '', $db = null) + { + if(!$method) + { + $method = 'query'; + } + + if(is_null($db)) + { + $db = $this->_db; + } + + try + { + $result = $db->$method(); + } + catch(Exception $e) + { + $this->setError($e->getMessage(), true); + + $result = null; + } + + return $result; + } + + /** + * Prepares a table for being able to iterate through its data sets + * + * For categories it is important that always the parent categories have to be migrated + * afore their sub-categories. So please pass the parameters $table and $parent_name + * if you are migrating categories. + * + * @param object $query A query object holding the query to use + * @param string $table Name of the database table to prepare + * @param string $parent_name Name of the column which holds the parent id of each category + * @param array $first_parents Array of category IDs which can be migrated first (main categories) + * @return void + * @since 2.0 + */ + protected function prepareTable($query, $table = null, $parent_name = null, $first_parents = array(0)) + { + $this->parent_name = $parent_name; + + if(is_null($this->_mainframe->getUserState('joom.migration.internal.counter'))) + { + $this->_mainframe->setUserState('joom.migration.internal.counter', 0); + } + + if($table && $parent_name) + { + $parent_cats = $this->_mainframe->getUserState('joom.migration.internal.parent_cats'); + if(is_null($parent_cats)) + { + if(!$this->otherDatabase || is_null($this->_db2)) + { + $db = $this->_db; + } + else + { + $db = $this->_db2; + } + + // Check whether 'joom_migrated' exists from previously failed migrations + $checkQuery = $db->getQuery(true) + ->select('COLUMN_NAME') + ->from('information_schema.COLUMNS') + ->where('TABLE_NAME = '.$db->q($table)) + ->where('COLUMN_NAME = '.$db->q('joom_migrated')); + $db->setQuery($checkQuery); + if($this->runQuery('loadResult', $db)) + { + $db->setQuery('ALTER TABLE '.$table.' DROP '.$db->qn('joom_migrated')); + $this->runQuery('', $db); + } + + // Add column 'joom_migrated' to be able to keep track of already migrated entries + $db->setQuery('ALTER TABLE '.$table.' ADD '.$db->qn('joom_migrated').' INT(1) NOT NULL default 0'); + if(!$this->runQuery('', $db)) + { + // If this fails we want to abort the whole migration + throw new RuntimeException('Could not add \'joom_migrated\' column which is essential for the migration.'); + } + + $this->_mainframe->setUserState('joom.migration.internal.parent_cats', $first_parents); + } + } + + $this->query = $query; + } + + /** + * Returns the next data object of the query specified with method 'prepareTable'. + * + * 'prepareTable' has to be called first once. + * + * @return object The next data object + * @since 2.0 + */ + protected function getNextObject() + { + if(!$this->otherDatabase || is_null($this->_db2)) + { + $db = $this->_db; + } + else + { + $db = $this->_db2; + } + + if($this->parent_name) + { + $parent_cats = $this->_mainframe->getUserState('joom.migration.internal.parent_cats'); + $this->query->clear('where') + ->where($this->parent_name.' IN ('.implode(',', $parent_cats).')') + ->where('joom_migrated = 0'); + } + + $counter = $this->_mainframe->getUserState('joom.migration.internal.counter'); + + $db->setQuery($this->query, $counter, 1); + + if(!$this->parent_name) + { + $counter++; + $this->_mainframe->setUserState('joom.migration.internal.counter', $counter); + } + + return $this->runQuery('loadObject', $db); + } + + /** + * Marks a table row as migrated. + * + * This is important for migrating categories + * @see method 'prepareTable' + * + * @param int $catid ID of the data set which has been migrated + * @param string $key Primary key name of the table $table + * @param string $table Name of the database table the row is in + * @return void + * @since 2.0 + */ + protected function markAsMigrated($catid, $key, $table) + { + if(!$this->otherDatabase || is_null($this->_db2)) + { + $db = $this->_db; + } + else + { + $db = $this->_db2; + } + + $parent_cats = $this->_mainframe->getUserState('joom.migration.internal.parent_cats'); + $parent_cats[] = (int) $catid; + $parent_cats = array_unique($parent_cats); + $this->_mainframe->setUserState('joom.migration.internal.parent_cats', $parent_cats); + + $query = $db->getQuery(true) + ->update($table) + ->set('joom_migrated = 1') + ->where($key.' = '.(int) $catid); + $db->setQuery($query); + $this->runQuery('', $db); + } + + /** + * Resets a table which was prepared for iteration with method 'prepareTable' + * + * This method must be called after the iteration has been finished + * + * @see method 'prepareTable' + * + * @param string $table Name of the table to reset + * @return void + * @since 2.0 + */ + protected function resetTable($table = '') + { + if(!$this->otherDatabase || is_null($this->_db2)) + { + $db = $this->_db; + } + else + { + $db = $this->_db2; + } + + if($this->parent_name && $table) + { + $db->setQuery('ALTER TABLE '.$table.' DROP '.$db->qn('joom_migrated')); + $this->runQuery('', $db); + } + + $this->query = null; + $this->parent_name = null; + $this->_mainframe->setUserState('joom.migration.internal.parent_cats', null); + $this->_mainframe->setUserState('joom.migration.internal.counter', null); + } + + /** + * Rebuilds the nested set tree + * + * This function has to be called after migrating all categories + * unless during migration the nested set tree wasn't already created + * + * @return void + * @since 2.0 + */ + protected function rebuild() + { + // Refresh page once before rebuilding category tree + // in order to have as much time for it as possible. + // Refreshing is only necessary if not executed from the command line. + if(!$this->isCli && !$this->_mainframe->getUserState('joom.migration.internal.refreshedForRebuild')) + { + $this->_mainframe->setUserState('joom.migration.internal.refreshedForRebuild', true); + + $this->writeLogfile('Refresh afore rebuilding category tree'); + $this->_mainframe->setUserState('joom.migration.internal.task', 'rebuild'); + $this->refresher->refresh(); + } + + $table = JTable::getInstance('joomgallerycategories', 'Table'); + + $this->writeLogfile('Build the nested set tree'); + if($table->rebuild()) + { + $this->writeLogfile('Nested set tree successfully built'); + } + else + { + $this->writeLogfile(' -> Error building the nested set tree'); + if($error = $table->getError()) + { + $this->setError($error); + } + } + } + + /** + * Creates images from the original one or moves the existing ones + * into the folders of their category. + * + * Required parameters are the first two ($row and $origimage) with $row being the data object with image + * information and $origimage being the path and filename of the image to migrate. $origimage will be the one + * stored in the original images directory of JoomGallery. + * You can also specify $detailimage and $thumbnail which will store them in the respective folders. If you + * don't specify them they will be created from the original image. + * + * [jimport('joomla.filesystem.file') has to be called afore] + * + * @param object $row Holds information about the new image + * @param string $origimage The original image + * @param string $detailimage The detail image + * @param string $thumbnail The thumbnail + * @param boolean $newfilename True if a new file name shall be generated for the files + * @param boolean $copy True if the image shall be copied into the new directory, not moved + * @param boolean $checkOwner Determines whether the owner ID shall be checked against the existing users + * @return boolean True on success, false otherwise + * @since 1.5.0 + */ + public function moveAndResizeImage($row, $origimage, $detailimage = null, $thumbnail = null, $newfilename = true, $copy = null, $checkOwner = null) + { + if(is_null($copy)) + { + $copy = $this->copyImages; + } + + if(is_null($checkOwner)) + { + $checkOwner = $this->checkOwner; + } + + // Some checks + if(!isset($row->id) || $row->id < 1) + { + $this->setError('Invalid image ID'); + + return false; + } + if(!isset($row->imgfilename)) + { + $this->setError('Image file name wasn\'t found.'); + + return false; + } + if(!isset($row->catid) || $row->catid < 1) + { + $this->setError('Invalid category ID'); + + return false; + } + else + { + // If image with category ID 1 comes in we have to set + // the category ID to the newly created one because + // category with ID 1 is the ROOT category in JoomGallery + if($row->catid == 1) + { + $row->catid = $this->newCatid; + } + } + if(!isset($row->catpath)) + { + $row->catpath = JoomHelper::getCatpath($row->catid); + if(!$row->catpath) + { + $this->setError('Category with ID '.$row->catid.' does not exist for image with ID '.$row->id.'. Image cannot be migrated.'); + + return false; + } + } + if(!isset($row->imgtitle)) + { + $row->imgtitle = str_replace(JFile::getExt($row->imgfilename), '', $row->imgfilename); + } + if(!isset($row->alias)) + { + // Will be created later on + $row->alias = ''; + } + if(!isset($row->imgauthor)) + { + $row->imgauthor = ''; + } + if(!isset($row->imgtext)) + { + $row->imgtext = ''; + } + if(!isset($row->imgdate) || is_numeric($row->imgdate)) + { + $date = JFactory::getDate(); + $row->imgdate = $date->toSQL(); + } + if(!isset($row->hits)) + { + $row->hits = 0; + } + if(!isset($row->downloads)) + { + $row->downloads = 0; + } + if(!isset($row->imgvotes)) + { + $row->imgvotes = 0; + } + if(!isset($row->imgvotesum)) + { + $row->imgvotesum = 0; + } + if(!isset($row->access) || $row->access < 1) + { + $row->access = $this->_mainframe->getCfg('access'); + } + if(!isset($row->published)) + { + $row->published = 0; + } + if(!isset($row->hidden)) + { + $row->hidden = 0; + } + if(!isset($row->imgthumbname)) + { + $row->imgthumbname = $row->imgfilename; + } + if(!isset($row->checked_out)) + { + $row->checked_out = 0; + } + if( !isset($row->owner) + || !is_numeric($row->owner) + || $row->owner < 1 + || ($checkOwner && !JUser::getTable()->load($row->owner)) + ) + { + $row->owner = 0; + } + if(!isset($row->approved)) + { + $row->approved = 1; + } + if(!isset($row->useruploaded)) + { + $row->useruploaded = 0; + } + if(!isset($row->ordering)) + { + $row->ordering = 0; + } + if(!isset($row->params)) + { + $row->params = ''; + } + if(!isset($row->metakey)) + { + $row->metakey = ''; + } + if(!isset($row->metadesc)) + { + $row->metadesc = ''; + } + + // Check whether one of the images to migrate already exist in the destination directory + $orig_exists = false; + $img_exists = false; + $thumb_exists = false; + $neworigimage = $this->_ambit->getImg('orig_path', $row); + $newdetailimage = $this->_ambit->getImg('img_path', $row); + $newthumbnail = $this->_ambit->getImg('thumb_path', $row); + if(JFile::exists($neworigimage)) + { + $orig_exists = true; + } + if(JFile::exists($newdetailimage)) + { + $img_exists = true; + } + if(JFile::exists($newthumbnail)) + { + $thumb_exists = true; + } + + // Generate a new file name if requested or if a file with the current name already exists + if($newfilename || $orig_exists || $img_exists || $thumb_exists) + { + $row->imgfilename = $this->genFilename($row->imgtitle, $origimage, $row->catid); + $row->imgthumbname = $row->imgfilename; + } + + $result = array(); + + // Copy or move original image into the folder of the original images + if(!$orig_exists) + { + // If it doesn't already exists with another name try to copy or move from source directory + if(!JFile::exists($origimage)) + { + $this->setError('Original image not found: '.$origimage); + + return false; + } + + $neworigimage = $this->_ambit->getImg('orig_path', $row); + if($copy) + { + $result['orig'] = JFile::copy(JPath::clean($origimage), + JPath::clean($neworigimage)); + if(!$result['orig']) + { + $this->setError('Could not copy original image from '.$origimage.' to '.$neworigimage); + + return false; + } + } + else + { + $result['orig'] = JFile::move(JPath::clean($origimage), + JPath::clean($neworigimage)); + if(!$result['orig']) + { + $this->setError('Could not move original image from '.$origimage.' to '.$neworigimage); + + return false; + } + } + } + else + { + // If it already exists with another name copy it to a file with the new name + if(!JFile::copy($neworigimage, $this->_ambit->getImg('orig_path', $row))) + { + $this->setError('Could not copy original image from '.$neworigimage.' to '.$this->_ambit->getImg('orig_path', $row)); + + return false; + } + + // Populate the new original file name and path because it will be + // necessary for deleting it of deleting original images is configured + $neworigimage = $this->_ambit->getImg('orig_path', $row); + } + + if(!$img_exists) + { + // If it doesn't already exists with another name try to copy or move from source directory or create a new one + $newdetailimage = $this->_ambit->getImg('img_path', $row); + if(is_null($detailimage) || !JFile::exists($detailimage)) + { + // Create new detail image + $debugoutput = ''; + $result['detail'] = JoomFile::resizeImage($debugoutput, + $neworigimage, + $newdetailimage, + false, + $this->_config->get('jg_maxwidth'), + false, + $this->_config->get('jg_thumbcreation'), + $this->_config->get('jg_thumbquality'), + true, + 0 + ); + if(!$result['detail']) + { + $this->setError('Could not create detail image '.$newdetailimage); + } + } + else + { + // Copy or move existing detail image + if($copy) + { + $result['detail'] = JFile::copy(JPath::clean($detailimage), + JPath::clean($newdetailimage)); + if(!$result['detail']) + { + $this->setError('Could not copy detail image from '.$detailimage.' to '.$newdetailimage); + } + } + else + { + $result['detail'] = JFile::move(JPath::clean($detailimage), + JPath::clean($newdetailimage)); + if(!$result['detail']) + { + $this->setError('Could not move detail image from '.$detailimage.' to '.$newdetailimage); + } + } + } + } + else + { + // If it already exists with another name copy it to a file with the new name + $result['detail'] = JFile::copy($newdetailimage, $this->_ambit->getImg('img_path', $row)); + if(!$result['detail']) + { + $this->setError('Could not copy detail image from '.$newdetailimage.' to '.$this->_ambit->getImg('img_path', $row)); + } + } + + if(!$thumb_exists) + { + // If it doesn't already exists with another name try to copy or move from source directory or create a new one + $newthumbnail = $this->_ambit->getImg('thumb_path', $row); + if(is_null($thumbnail) || !JFile::exists($thumbnail)) + { + // Create new thumbnail + $debugoutput = ''; + $result['thumb'] = JoomFile::resizeImage( $debugoutput, + $neworigimage, + $newthumbnail, + $this->_config->get('jg_useforresizedirection'), + $this->_config->get('jg_thumbwidth'), + $this->_config->get('jg_thumbheight'), + $this->_config->get('jg_thumbcreation'), + $this->_config->get('jg_thumbquality'), + false, + $this->_config->get('jg_cropposition') + ); + if(!$result['thumb']) + { + $this->setError('Could not create thumbnail '.$newthumbnail); + } + } + else + { + // Copy or move existing thumbnail + if($copy) + { + $result['thumb'] = JFile::copy(JPath::clean($thumbnail), + JPath::clean($newthumbnail)); + if(!$result['thumb']) + { + $this->setError('Could not copy thumbnail from '.$thumbnail.' to '.$newthumbnail); + } + } + else + { + $result['thumb'] = JFile::move(JPath::clean($thumbnail), + JPath::clean($newthumbnail)); + if(!$result['thumb']) + { + $this->setError('Could not move thumbnail from '.$thumbnail.' to '.$newthumbnail); + } + } + } + } + else + { + // If it already exists with another name copy it to a file with the new name + $result['thumb'] = JFile::copy($newthumbnail, $this->_ambit->getImg('thumb_path', $row)); + if(!$result['thumb']) + { + $this->setError('Could not copy thumbnail from '.$newthumbnail.' to '.$this->_ambit->getImg('thumb_path', $row)); + } + } + + // Delete original image if configured in JoomGallery + if($this->_config->get('jg_delete_original') == 1) + { + $result['delete_orig'] = JFile::delete($neworigimage); + if(!$result['delete_orig']) + { + $this->setError('Could not delete original image '.$neworigimage); + } + } + + // Create database entry + $query = $this->_db->getQuery(true) + ->insert(_JOOM_TABLE_IMAGES) + ->columns('id, catid, imgtitle, alias, imgauthor, imgtext, imgdate, hits, downloads, imgvotes, imgvotesum, access, published, hidden, imgfilename, imgthumbname, checked_out, owner, approved, useruploaded, ordering, params, metakey, metadesc') + ->values( (int) $row->id.','. + (int) $row->catid.','. + $this->_db->quote($row->imgtitle).','. + $this->_db->quote($row->alias).','. + $this->_db->quote($row->imgauthor).','. + $this->_db->quote($row->imgtext).','. + $this->_db->quote($row->imgdate).','. + (int) $row->hits.','. + (int) $row->downloads.','. + (int) $row->imgvotes.','. + (int) $row->imgvotesum.','. + (int) $row->access.','. + (int) $row->published.','. + (int) $row->hidden.','. + $this->_db->quote($row->imgfilename).','. + $this->_db->quote($row->imgthumbname).','. + (int) $row->checked_out.','. + (int) $row->owner.','. + (int) $row->approved.','. + (int) $row->useruploaded.','. + (int) $row->ordering.','. + $this->_db->quote($row->params).','. + $this->_db->quote($row->metakey).','. + $this->_db->quote($row->metadesc) + ); + $this->_db->setQuery($query); + $result[] = $this->runQuery(); + + // Create asset and alias + $table = JTable::getInstance('joomgalleryimages', 'Table'); + $table->load($row->id); + if($table->check()) + { + $result['db'] = $table->store(); + if(!$result['db']) + { + $this->setError($table->getError(), true); + } + } + + if(!in_array(false, $result)) + { + $this->writeLogfile('Image successfully migrated: ' . $row->id . ' Title: ' . $row->imgtitle); + + return true; + } + else + { + $this->writeLogfile('-> Error migrating image: ' . $row->id . ' Title: ' . $row->imgtitle); + + return false; + } + } + + /** + * Creates a comment + * + * @param object $row Holds the comment data + * @return boolean True on success, false otherwise + * @since 1.5.0 + */ + public function createComment($row) + { + // Some checks + if(!isset($row->cmtpic) || !$row->cmtpic) + { + $this->setError('Invalid image ID for comment'); + + return false; + } + if(!isset($row->cmttext) || $row->cmttext == '') + { + $this->setError('Comment hasn\'t any text'); + + return false; + } + if(!isset($row->cmtid)) + { + $row->cmtid = 0; + } + if(!isset($row->cmtip)) + { + $row->cmtip = '127.0.0.1'; + } + if(!isset($row->userid)) + { + $row->userid = 0; + } + if(!isset($row->cmtname)) + { + $row->cmtname = ''; + } + if(!isset($row->cmtdate) || is_numeric($row->cmtdate)) + { + $date = JFactory::getDate(); + $row->cmtdate = $date->toSQL(); + } + if(!isset($row->published)) + { + $row->published = 0; + } + if(!isset($row->approved)) + { + $row->approved = 1; + } + + // Create database entry + $values = array((int) $row->cmtpic, + $this->_db->quote($row->cmtip), + (int) $row->userid, + $this->_db->quote($row->cmtname), + $this->_db->quote($row->cmttext), + $this->_db->quote($row->cmtdate), + (int) $row->published, + (int) $row->approved + ); + + $query = $this->_db->getQuery(true) + ->insert(_JOOM_TABLE_COMMENTS); + + if($row->cmtid) + { + $query->columns('cmtid'); + array_unshift($values, $row->cmtid); + } + + $query->columns('cmtpic, cmtip, userid, cmtname, cmttext, cmtdate, published, approved') + ->values(implode(',', $values)); + $this->_db->setQuery($query); + if($this->runQuery()) + { + $this->writeLogfile('Comment with ID '.$row->cmtid.' successfully stored'); + + return true; + } + + return false; + } + + /** + * Creates a name tag + * + * @param object $row Holds the name tag data + * @return boolean True on success, false otherwise + * @since 1.5.0 + */ + public function createNametag($row) + { + // Some checks + if(!isset($row->npicid) || !$row->npicid) + { + $this->setError('Invalid image ID for name tag'); + + return false; + } + if(!isset($row->nxvalue) || $row->nxvalue < 0) + { + $this->setError('Invalid x value for name tag'); + + return false; + } + if(!isset($row->nyvalue) || $row->nyvalue < 0) + { + $this->setError('Invalid y value for name tag'); + + return false; + } + if(!isset($row->nid)) + { + $row->nid = 0; + } + if(!isset($row->nuserid)) + { + $row->nuserid = 0; + } + if(!isset($row->by)) + { + $row->by = 0; + } + if(!isset($row->nuserip)) + { + $row->cmtip = '127.0.0.1'; + } + if(!isset($row->ndate) || is_numeric($row->ndate)) + { + $date = JFactory::getDate(); + $row->ndate = $date->toSQL(); + } + if(!isset($row->nzindex)) + { + $row->nzindex = 500; + } + + // Create database entry + $query = $this->_db->getQuery(true) + ->insert(_JOOM_TABLE_NAMESHIELDS); + + $values = array((int) $row->npicid, + (int) $row->nuserid, + (int) $row->nxvalue, + (int) $row->nyvalue, + (int) $row->by, + $this->_db->quote($row->nuserip), + $this->_db->quote($row->ndate), + (int) $row->nzindex + ); + if($row->nid) + { + $query->columns('nid'); + array_unshift($values, $row->nid); + } + + $query->columns('npicid, nuserid, nxvalue, nyvalue, '.$this->_db->quoteName('by').', nuserip, ndate, nzindex') + ->values(implode(',', $values)); + $this->_db->setQuery($query); + if($this->runQuery()) + { + $this->writeLogfile('Name tag with ID '.$row->nid.' successfully stored'); + + return true; + } + + return false; + } + + /** + * Creates a user record + * + * @param object $row Holds the user data + * @return boolean True on success, false otherwise + * @since 3.1 + */ + public function createUser($row) + { + // Some checks + if(!isset($row->uuserid) || !$row->uuserid) + { + $this->setError('Invalid user ID for user record'); + + return false; + } + if(!isset($row->uid)) + { + $row->uid = 0; + } + if(!isset($row->piclist)) + { + $row->piclist = ''; + } + if(!isset($row->layout)) + { + $row->layout = 0; + } + if(!isset($row->time)) + { + $row->time = JFactory::getDate()->toSql(); + } + if(!isset($row->zipname) || !$row->zipname) + { + $row->zipname = ''; + } + + // Create database entry + $values = array((int) $row->uuserid, + $this->_db->quote($row->piclist), + (int) $row->layout, + $this->_db->quote($row->time), + $this->_db->quote($row->zipname) + ); + + $query = $this->_db->getQuery(true) + ->insert(_JOOM_TABLE_USERS); + + if((int) $row->uid) + { + $query->columns('uid'); + array_unshift($values, (int) $row->uid); + } + + $query->columns('uuserid, piclist, layout, time, zipname') + ->values(implode(',', $values)); + $this->_db->setQuery($query); + if($this->runQuery()) + { + $this->writeLogfile('User record with ID '.((int) $row->uid).' successfully stored'); + + return true; + } + + return false; + } + + /** + * Creates a vote record + * + * @param object $row Holds the vote data + * @return boolean True on success, false otherwise + * @since 3.1 + */ + public function createVote($row) + { + // Some checks + if(!isset($row->picid) || !$row->picid) + { + $this->setError('Invalid image ID for vote record'); + + return false; + } + if(!isset($row->voteid)) + { + $row->voteid = 0; + } + if(!isset($row->userid)) + { + $row->userid = 0; + } + if(!isset($row->userip)) + { + $row->userip = '127.0.0.1'; + } + if(!isset($row->datevoted) || is_numeric($row->datevoted)) + { + $date = JFactory::getDate(); + $row->datevoted = $date->toSQL(); + } + if(!isset($row->vote) || !$row->vote) + { + $row->vote = 0; + } + + // Create database entry + $values = array((int) $row->picid, + (int) $row->userid, + $this->_db->quote($row->userip), + $this->_db->quote($row->datevoted), + (int) $row->vote + ); + + $query = $this->_db->getQuery(true) + ->insert(_JOOM_TABLE_VOTES); + + if($row->voteid) + { + $query->columns('voteid'); + array_unshift($values, $row->voteid); + } + + $query->columns('picid, userid, userip, datevoted, vote') + ->values(implode(',', $values)); + $this->_db->setQuery($query); + if($this->runQuery()) + { + $this->writeLogfile('Vote record with ID '.$row->voteid.' successfully stored'); + + return true; + } + + return false; + } + + /** + * Generates a new filename + * e.g. __. + * + * @param string $title The title of the image + * @param string $file Path and file name of the old image file + * @param int $catid ID of the category into which the image will be stored + * @param string $tag File extension e.g. 'jpg' + * @return string The generated filename + * @since 2.0 + */ + protected function genFilename($title, $file, $catid) + { + $date = date('Ymd'); + + $tag = strtolower(JFile::getExt($file)); + + $filename = JoomFile::fixFilename($title); + + // Remove filetag = $tag incl '.' + $filename = substr($filename, 0, strlen($filename)-strlen($tag)-1); + + do + { + mt_srand(); + $randomnumber = mt_rand(1000000000, 2099999999); + + // New filename + $newfilename = $filename.'_'.$date.'_'.$randomnumber.'.'.$tag; + } + while( JFile::exists($this->_ambit->getImg('orig_path', $newfilename, null, $catid)) + || JFile::exists($this->_ambit->getImg('img_path', $newfilename, null, $catid)) + || JFile::exists($this->_ambit->getImg('thumb_path', $newfilename, null, $catid)) + ); + + return $newfilename; + } +} diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/helpers/migration/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/helpers/migration/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/helpers/migration/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/helpers/openimageplugin.php b/deployed/joomgallery/administrator/components/com_joomgallery/helpers/openimageplugin.php new file mode 100644 index 00000000..a20a0f9f --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/helpers/openimageplugin.php @@ -0,0 +1,163 @@ + + * $doc = JFactory::getDocument(); + * $doc->addStyleSheet(JUri::root().'media/plg_exampleopenimage/css/exampleopenimage.css'); + * $doc->addScript(JUri::root().'media/plg_exampleopenimage/js/exampleopenimage.js'); + * $doc->addScriptDeclaration(" jQuery(document).ready(function(){ExampleOpenImage.init()}"); + * + * + * or if using Mootools or jQuery the respective JHtml method: + * + * JHtml::_('jquery.framework'); + * JHtml::_('behavior.framework'); + * + * + * @return void + * @since 3.0 + */ + abstract protected function init(); + + /** + * OnJoomOpenImage method + * + * Method is called when an image of JoomGallery shall be opened. + * It modifies the given link in order to use the respective box for opening the image. + * + * @access public + * @param string $link The link to modify + * @param object $image An object holding the image data + * @param string $img_url The URL to the image which shall be openend + * @param string $group The name of an image group, most boxes will make an album out of the images of a group + * @param string $type 'orig' for original image, 'img' for detail image or 'thumb' for thumbnail + * @param string $selected If a specific box was selected it will be delivered in this argument + * @return void + * @since 3.0 + */ + public function onJoomOpenImage(&$link, $image = null, $img_url = null, $group = 'joomgallery', $type = 'orig', $selected = null) + { + if(!$image) + { + // Let JoomGallery know that this plugin is enabled (this is for backwards compatibility only) + $link = true; + + return; + } + + if($selected && $selected != $this->title) + { + // If an OpenImage plugin was selected but not this one we don't do anything here + return; + } + + // Ensure that the necessary assets are loaded once (if necessary) + static $loaded = false; + if(!$loaded && !$this->params->get('global_box_existent')) + { + $this->init(); + $loaded = true; + } + + // Get all the attributes for the link tag + $attribs = array('href' => $img_url); + $this->getLinkAttributes($attribs, $image, $img_url, $group, $type); + + $href = $img_url; + if(isset($attribs['href'])) + { + $href = $attribs['href']; + unset($attribs['href']); + } + + if(!count($attribs)) + { + $link = $href; + + return; + } + + $attribs = JArrayHelper::toString($attribs); + + // Remove the last quotation marks and create the tag + $link = $href.'" '.substr($attribs, 0, -1); + } + + /** + * This method should set an associative array of attributes for the 'a'-Tag (key/value pairs) which opens the image. + * + * + * $attribs['data-rel'] = 'examplebox'; + * $attribs['data-group'] = $group; + * + * + * The example above will create a link tag like that: + * + * ($attribs is passed by references and should only be filled) + * + * By default the attribute 'href' is filled with the URL to the image which shall be opened. You only have to set that + * attribute if you want to change that (the image URL is passed in the third argument of this method). + * + * NOTE!!!: You are not allowed to set the attributes 'title' and 'class' because these are handled internally by JoomGallery. + * + * @param array $attribs Associative array of HTML attributes which you have to fill + * @param object $image An object holding all the relevant data about the image to open + * @param string $img_url The URL to the image which shall be openend + * @param string $group The name of an image group, most popup boxes are able to group the images with that + * @param string $type 'orig' for original image, 'img' for detail image or 'thumb' for thumbnail + * @return void + * @since 3.0 + */ + abstract protected function getLinkAttributes(&$attribs, $image, $img_url, $group, $type); + + /** + * onJoomOpenImageGetName method + * + * Method is called if the popup box name is requested used by this plugin + * + * @return string The name of the popup box used by this plugin + * @since 3.0 + */ + public function onJoomOpenImageGetName() + { + return $this->title; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/helpers/pagination.php b/deployed/joomgallery/administrator/components/com_joomgallery/helpers/pagination.php new file mode 100644 index 00000000..31344e00 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/helpers/pagination.php @@ -0,0 +1,343 @@ +anchortag = ''; + if($anchortag) + { + $this->anchortag = JHtml::_('joomgallery.anchor', $anchortag); + } + + if($onclick) + { + $this->onclick = '" onclick="'.$onclick; + } + } + + /** + * Create and return the pagination data object + * + * @return object Pagination data object + * @since 2.0 + */ + protected function _buildDataObject() + { + // Check whether the data object was already created + if(!empty($this->store)) + { + return $this->store; + } + + // Initialise variables + $data = new stdClass; + $currentPage = $this->get('pages.current'); + $pageCount = $this->get('pages.total'); + + // Build the additional URL parameters string + $params = ''; + if(!empty($this->additionalUrlParams)) + { + foreach($this->additionalUrlParams as $key => $value) + { + $params .= '&'.$key.'='.$value; + } + } + + $data->all = new JPaginationObject(JText::_('JLIB_HTML_VIEW_ALL'), $this->prefix); + if(!$this->viewall) + { + $data->all->base = '0'; + $data->all->link = JRoute::_($params.'&'.$this->prefix.'limitstart='); + } + + // Set the start and previous data objects + $data->start = new JPaginationObject(JText::_('JLIB_HTML_START'), $this->prefix); + $data->previous = new JPaginationObject(JText::_('JPREV'), $this->prefix); + + if($currentPage > 1) + { + $previous = $currentPage - 1; + + $data->start->base = 1; + $data->start->link = JRoute::_($params.'&'.$this->prefix.'page=1').$this->anchortag.sprintf($this->onclick, 1); + $data->previous->base = $previous; + $data->previous->link = JRoute::_($params.'&'.$this->prefix.'page='.$previous).$this->anchortag.sprintf($this->onclick, $previous); + } + + // Set the next and end data objects + $data->next = new JPaginationObject(JText::_('JNEXT'), $this->prefix); + $data->end = new JPaginationObject(JText::_('JLIB_HTML_END'), $this->prefix); + + if($currentPage < $pageCount) + { + $next = $currentPage + 1; + + $data->next->base = $next; + $data->next->link = JRoute::_($params.'&'.$this->prefix.'page='.$next).$this->anchortag.sprintf($this->onclick, $next); + $data->end->base = $pageCount; + $data->end->link = JRoute::_($params.'&'.$this->prefix.'page='.$pageCount).$this->anchortag.sprintf($this->onclick, $pageCount); + } + + $data->pages = array(); + + $workPage = 2; + $placeHolderKey = $pageCount; + + // Variable for current page found and assembled + $currItemfound = false; + + // Work on left edge + if($currentPage == 1) + { + $currItemfound = true; + $data->pages[1] = new JPaginationObject(1, $this->prefix); + $data->pages[1]->base = null; + $data->pages[1]->link = JRoute::_($params.'&'.$this->prefix.'page=1').$this->anchortag.sprintf($this->onclick, 1); + $data->pages[2] = new JPaginationObject(2, $this->prefix); + $data->pages[2]->base = 2; + $data->pages[2]->link = JRoute::_($params.'&'.$this->prefix.'page=2').$this->anchortag.sprintf($this->onclick, 2); + } + else + { + // Current page not 1 + $data->pages[1] = new JPaginationObject(1, $this->prefix); + $data->pages[1]->base = 1; + $data->pages[1]->link = JRoute::_($params.'&'.$this->prefix.'page=1').$this->anchortag.sprintf($this->onclick, 1); + + if($currentPage == 2) + { + $currItemfound = true; + $data->pages[2] = new JPaginationObject(2, $this->prefix); + $data->pages[2]->base = null; + $data->pages[2]->link = JRoute::_($params.'&'.$this->prefix.'page=2').$this->anchortag.sprintf($this->onclick, 2); + } + else + { + $data->pages[2] = new JPaginationObject(2, $this->prefix); + $data->pages[2]->base = 2; + $data->pages[2]->link = JRoute::_($params.'&'.$this->prefix.'page=2').$this->anchortag.sprintf($this->onclick, 2); + } + } + + // Range left from current page to 1 not assembled yet + if(!$currItemfound) + { + // Construct pages left to current page + // according to difference to left implement jumps + // If difference to current page too low, output them exactly + if($currentPage - $workPage < 6) + { + $workPage++; + for($i = $workPage; $i < $currentPage; $i++) + { + $data->pages[$i] = new JPaginationObject($i, $this->prefix); + $data->pages[$i]->base = $i; + $data->pages[$i]->link = JRoute::_($params.'&'.$this->prefix.'page='.$i).$this->anchortag.sprintf($this->onclick, $i); + $workPage++; + } + } + else + { + // Otherwise output of remaining links evt. in steps + // and in addition output of 2 left neighbours + // completion of range at position 3 to (current page - 3) + $endRange = $currentPage - 3; + $jump = ceil(($endRange - 5) / 4); + if($jump == 0) + { + $jump = 1; + } + + $workPage = $workPage + $jump; + for($i = 1; $i < 4; $i++) + { + if($jump != 1) + { + $placeHolderKey++; + $data->pages[$placeHolderKey] = new JPaginationObject(JText::_('COM_JOOMGALLERY_COMMON_PAGENAVIGATION_ELLIPSIS'), $this->prefix); + $data->pages[$placeHolderKey]->base = null; + } + + $data->pages[$workPage] = new JPaginationObject($workPage, $this->prefix); + $data->pages[$workPage]->base = $workPage; + $data->pages[$workPage]->link = JRoute::_($params.'&'.$this->prefix.'page='.$workPage).$this->anchortag.sprintf($this->onclick, $workPage); + $workPage = $workPage + $jump; + } + + if($workPage != ($currentPage - 2)) + { + $placeHolderKey++; + $data->pages[$placeHolderKey] = new JPaginationObject(JText::_('COM_JOOMGALLERY_COMMON_PAGENAVIGATION_ELLIPSIS'), $this->prefix); + $data->pages[$placeHolderKey]->base = null; + } + // Output of 2 pages left beside current page + $data->pages[$currentPage - 2] = new JPaginationObject($currentPage - 2, $this->prefix); + $data->pages[$currentPage - 2]->base = $currentPage - 2; + $data->pages[$currentPage - 2]->link = JRoute::_($params.'&'.$this->prefix.'page='.($currentPage - 2)).$this->anchortag.sprintf($this->onclick, $currentPage - 2); + $data->pages[$currentPage - 1] = new JPaginationObject($currentPage - 1, $this->prefix); + $data->pages[$currentPage - 1]->base = $currentPage - 1; + $data->pages[$currentPage - 1]->link = JRoute::_($params.'&'.$this->prefix.'page='.($currentPage - 1)).$this->anchortag.sprintf($this->onclick, $currentPage - 1); + } + + // Current page + $data->pages[$currentPage] = new JPaginationObject($currentPage, $this->prefix); + $data->pages[$currentPage]->base = null; + $data->pages[$currentPage]->link = JRoute::_($params.'&'.$this->prefix.'page='.$currentPage).$this->anchortag.sprintf($this->onclick, $currentPage); + $currItemfound = true; + $workPage = $currentPage; + } + + // Current page found, right beside construct 2 pages + // max to end + if($pageCount - $workPage < 3) + { + $endRangecount = $pageCount - $workPage; + } + else + { + $endRangecount = 2; + } + + $workPage++; + for($i = 1; $i <= $endRangecount; $i++) + { + $data->pages[$workPage] = new JPaginationObject($workPage, $this->prefix); + $data->pages[$workPage]->base = $workPage; + $data->pages[$workPage]->link = JRoute::_($params.'&'.$this->prefix.'page='.$workPage).$this->anchortag.sprintf($this->onclick, $workPage); + $workPage++; + } + + if($workPage == $pageCount) + { + $data->pages[$workPage] = new JPaginationObject($workPage, $this->prefix); + $data->pages[$workPage]->base = $workPage; + $data->pages[$workPage]->link = JRoute::_($params.'&'.$this->prefix.'page='.$workPage).$this->anchortag.sprintf($this->onclick, $workPage); + + $this->store = $data; + + return $data; + } + + // All ready + if($workPage > $pageCount) + { + $this->store = $data; + + return $data; + } + + // If only 3 pages to end remain + if($workPage < $pageCount && ($pageCount - $workPage) < 7) + { + for($i = $workPage; $i <= $pageCount; $i++) + { + $data->pages[$workPage] = new JPaginationObject($workPage, $this->prefix); + $data->pages[$workPage]->base = $workPage; + $data->pages[$workPage]->link = JRoute::_($params.'&'.$this->prefix.'page='.$workPage).$this->anchortag.sprintf($this->onclick, $workPage); + $workPage++; + } + } + else + { + // Output of remaining pages in steps + // and in addition output of last page and the neighbour left + // Complete the range (current page + 3) to (last page - 3) + $startRange = $workPage; + $endRange = $pageCount - 3; + $jump = ceil(($endRange - $startRange) / 4); + $workPage = $workPage + $jump; + for($i = 1; $i < 4; $i++) + { + if($jump != 1) + { + $placeHolderKey++; + $data->pages[$placeHolderKey] = new JPaginationObject(JText::_('COM_JOOMGALLERY_COMMON_PAGENAVIGATION_ELLIPSIS'), $this->prefix); + $data->pages[$placeHolderKey]->base = null; + } + + $data->pages[$workPage] = new JPaginationObject($workPage, $this->prefix); + $data->pages[$workPage]->base = $workPage; + $data->pages[$workPage]->link = JRoute::_($params.'&'.$this->prefix.'page='.$workPage).$this->anchortag.sprintf($this->onclick, $workPage); + $workPage = $workPage + $jump; + } + + $placeHolderKey++; + $data->pages[$placeHolderKey] = new JPaginationObject(JText::_('COM_JOOMGALLERY_COMMON_PAGENAVIGATION_ELLIPSIS'), $this->prefix); + $data->pages[$placeHolderKey]->base = null; + + // Output of penultimate and last + $data->pages[$pageCount - 1] = new JPaginationObject($pageCount - 1, $this->prefix); + $data->pages[$pageCount - 1]->base = $pageCount - 1; + $data->pages[$pageCount - 1]->link = JRoute::_($params.'&'.$this->prefix.'page='.($pageCount - 1)).$this->anchortag.sprintf($this->onclick, $pageCount - 1); + $data->pages[$pageCount] = new JPaginationObject($pageCount, $this->prefix); + $data->pages[$pageCount]->base = $pageCount; + $data->pages[$pageCount]->link = JRoute::_($params.'&'.$this->prefix.'page='.$pageCount).$this->anchortag.sprintf($this->onclick, $pageCount); + } + + $this->store = $data; + + return $data; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/helpers/refresher.php b/deployed/joomgallery/administrator/components/com_joomgallery/helpers/refresher.php new file mode 100644 index 00000000..3897a7b4 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/helpers/refresher.php @@ -0,0 +1,362 @@ +_mainframe = JFactory::getApplication('administrator'); + + if(isset($params['controller'])) + { + $this->_controller = $params['controller']; + } + else + { + $this->_controller = JRequest::getCmd('controller'); + } + + if(isset($params['task'])) + { + $this->_task = $params['task']; + } + else + { + $this->_task = JRequest::getCmd('task'); + } + + if(isset($params['msg'])) + { + $this->_msg = $params['msg']; + } + else + { + $this->_msg = false; + } + + if(isset($params['remaining'])) + { + $this->_remaining = $params['remaining']; + + if(isset($params['start']) && $params['start']) + { + $this->_total = $params['remaining']; + $this->_mainframe->setUserState('joom.refresher.total', $this->_total); + } + else + { + $this->_total = $this->_mainframe->getUserState('joom.refresher.total'); + } + + $this->_showprogress = $this->_total ? true : false; + } + + if(isset($params['name']) && $params['name']) + { + $this->_name = $params['name']; + } + + $this->init(); + } + + /** + * Initializes the refresher by storing current time + * + * @return void + * @since 1.5.5 + */ + public function init() + { + // Check the maximum execution time of the script + $max_execution_time = @ini_get('max_execution_time'); + + // Set secure setting of the real execution time + // Maximum time for the script will be set to 20 seconds + // (max_exection_time = 0 means no limit) + if($max_execution_time < 25 && $max_execution_time != 0) + { + $this->_maxtime = (int) $max_execution_time * 0.8; + } + else + { + $this->_maxtime = 20; + } + + $this->_starttime = time(); + } + + /** + * Returns the calculated maximum execution time + * + * @return int The calculated maximum execution time + * @since 3.2 + */ + public function getMaxTime() + { + return $this->_maxtime; + } + + /** + * Resets the progressbar or the name of the current task + * + * @param int $remaining Number of remaining steps + * @param boolean $start Determines whether $remaining holds the total number of steps + * @param string $name Name of the task to display + * @return void + * @since 1.5.6 + */ + public function reset($remaining = null, $start = null, $name = null) + { + if(!is_null($remaining)) + { + $this->_remaining = $remaining; + + if(!is_null($start) && $start) + { + $this->_total = $remaining; + $this->_mainframe->setUserState('joom.refresher.total', $this->_total); + } + else + { + $this->_total = $this->_mainframe->getUserState('joom.refresher.total'); + } + + $this->_showprogress = $this->_total ? true : false; + } + else + { + $this->_showprogress = false; + } + + if(!is_null($name) && $name) + { + $this->_name = $name; + } + } + + /** + * Checks the remaining time + * + * @return boolean True: Time remains, false: No more time left + * @since 1.5.5 + */ + public function check() + { + $timeleft = -(time() - $this->_starttime - $this->_maxtime); + if($timeleft > 3) + { + return true; + } + + return false; + } + + /** + * Make a redirect + * + * @param int $remaining Number of remaining steps + * @param string $task The task which will be called after the redirect + * @param string $msg An optional message which will be enqueued (this is currently disabled) + * @param string $type Type of the message (one of 'message', 'notice', 'error') + * @param string $controller The controller which will be called after the redirect + * @return void + * @since 1.5.5 + */ + public function refresh($remaining = null, $task = null, $msg = null, $type = null, $controller = null) + { + if($remaining) + { + $this->_remaining = $remaining; + } + + if($this->_msg && is_null($task)) + { + $this->_mainframe->enqueueMessage(JText::_('COM_JOOMGALLERY_COMMON_REDIRECT')); + } + if(!$task) + { + $task = $this->_task; + } + if(!$controller) + { + $controller = $this->_controller; + } + + if($msg) + { + $this->_mainframe->enqueueMessage($msg, $type); + } + + if(!$this->_msg || $msg) + { + // Persist messages if they exist + $messages = $this->_mainframe->getMessageQueue(); + if(count($messages)) + { + $session = JFactory::getSession(); + $session->set('application.queue', $messages); + } + } + + $url = 'index.php?option='._JOOM_OPTION.'&controller='.$controller.'&task='.$task; + $onclick = 'document.location.href=\''.$url.'\';'; + + $buffer = ''; + if($buffer = ob_get_contents()) + { + ob_end_clean(); + } + + echo ''; ?> + + + + + + + + isRTL()): ?> + + + + <?php echo JText::_('COM_JOOMGALLERY_COMMON_REFRESHER_IN_PROGRESS'); ?> + + +
    +
    +
    + +_name): ?> +
    + '.$this->_name.''); ?> + +
    +

    Spinner

    +_showprogress): ?> +
    +
    +
    +
    _maxtime); ?>
    +_msg): + $doc = JFactory::getDocument(); + $renderer = $doc->loadRenderer('message'); + echo $renderer->render(''); + endif; ?> +
    +
    +
    + + +_mainframe->close(); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/helpers/upload.php b/deployed/joomgallery/administrator/components/com_joomgallery/helpers/upload.php new file mode 100644 index 00000000..28501a2c --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/helpers/upload.php @@ -0,0 +1,2294 @@ +_mainframe = JFactory::getApplication(); + $this->_config = JoomConfig::getInstance(); + $this->_ambit = JoomAmbit::getInstance(); + $this->_user = JFactory::getUser(); + $this->_db = JFactory::getDBO(); + + $this->debug = $this->_mainframe->getUserStateFromRequest('joom.upload.debug', 'debug', false, 'post', 'bool'); + $this->_debugoutput = $this->_mainframe->getUserStateFromRequest('joom.upload.debugoutput', 'debugoutput', '', 'post', 'string'); + $this->catid = $this->_mainframe->getUserStateFromRequest('joom.upload.catid', 'catid', 0, 'int'); + $this->imgtitle = $this->_mainframe->getUserStateFromRequest('joom.upload.title', 'imgtitle', '', 'string'); + + $this->counter = $this->getImageNumber(); + + $this->_site = $this->_mainframe->isSite(); + + // TODO Parameter in JoomGallery configuration neccessary ? + // Create folder for image chunks + $this->chunksFolder = $this->_mainframe->getCfg('tmp_path').'/joomgallerychunks'; + if(!JFolder::exists($this->chunksFolder)) + { + JFolder::create($this->chunksFolder); + JoomFile::copyIndexHtml($this->chunksFolder); + } + } + + /** + * Returns the debug output + * + * @return mixed The debug output or false if debug is not enabled or debug output is empty. + * @since 3.0 + */ + public function getDebugOutput() + { + if($this->debug && !empty($this->_debugoutput)) + { + return $this->_debugoutput; + } + + return false; + } + + /** + * Calls the correct upload method according to the specified type + * + * @return boolean True on success, false otherwise + * @since 1.5.0 + */ + public function upload($type = 'single') + { + // Additional security check for unregistered users + if(!$this->_user->get('id') && !$this->_config->get('jg_unregistered_permissions')) + { + $this->setError(JText::_('COM_JOOMGALLERY_COMMON_MSG_YOU_ARE_NOT_LOGGED')); + + return false; + } + + jimport('joomla.filesystem.file'); + + switch($type) + { + case 'batch': + return $this->uploadBatch(); + break; + case 'java': + return $this->uploadJava(); + break; + case 'ftp': + return $this->uploadFTP(); + break; + case 'ajax': + return $this->uploadAJAX(); + break; + default: + return $this->uploadSingles(); + break; + } + } + + /** + * Deletes all file parts in the chunks folder for files uploaded + * more than chunksExpireIn seconds ago + * + * @return void + * @since 3.0 + */ + protected function cleanupChunks() + { + if(is_writable($this->chunksFolder) && 1 == mt_rand(1, 1/$this->chunksCleanupProbability)) + { + if(($folders = JFolder::folders($this->chunksFolder, '.', false, true)) !== false) + { + foreach($folders as $folder) + { + if(($files = JFolder::files($folder, '.', false, true)) !== false) + { + foreach($files as $file) + { + if(time() - filemtime($file) > $this->chunksExpireIn) + { + JFolder::delete($folder); + break; + } + } + } + } + } + } + } + + /** + * Single upload + * + * A number of images is chosen and uploaded afore. + * + * @return void + * @since 1.0.0 + */ + protected function uploadSingles() + { + // Access check + $category = $this->getCategory($this->catid); + if( !$category + || ( !$this->_user->authorise('joom.upload', _JOOM_OPTION.'.category.'.$this->catid) + && ( !$this->_user->authorise('joom.upload.inown', _JOOM_OPTION.'.category.'.$this->catid) + || !$category->owner + || $category->owner != $this->_user->get('id') + ) + ) + ) + { + $this->setError(JText::_('COM_JOOMGALLERY_COMMON_MSG_YOU_ARE_NOT_ALLOWED_TO_UPLOAD_INTO_THIS_CATEGORY')); + + return false; + } + + $this->_debugoutput .= '

    '; + $images = JRequest::getVar('arrscreenshot', '', 'files'); + + for($i = 0; $i < count($images['error'])/*$this->_config->get('jg_maxuploadfields')*/; $i++) + { + $this->_debugoutput .= '
    '; + $this->_debugoutput .= JText::sprintf('COM_JOOMGALLERY_UPLOAD_POSITION', $i + 1).'
    '; + + // Any image entry at position? + // (4=UPLOAD_ERR_NO_FILE constant since PHP 4.3.0) + // If not continue with next entry without setting 'debug' to 'true'. + if($images['error'][$i] == 4) + { + $this->_debugoutput .= JText::_('COM_JOOMGALLERY_UPLOAD_ERROR_FILE_NOT_UPLOADED').'
    '; + continue; + } + + // Check all other error codes + if($images['error'][$i] > 0) + { + $this->_debugoutput .= $this->checkError($images['error'][$i]).'
    '; + $this->debug = true; + continue; + } + + if($this->_site && $this->counter > $this->_config->get('jg_maxuserimage') - 1 && $this->_user->get('id')) + { + $timespan = $this->_config->get('jg_maxuserimage_timespan'); + $this->_debugoutput .= JText::sprintf('COM_JOOMGALLERY_UPLOAD_OUTPUT_MAY_ADD_MAX_OF', $this->_config->get('jg_maxuserimage'), $timespan > 0 ? JText::plural('COM_JOOMGALLERY_UPLOAD_NEW_IMAGE_MAXCOUNT_TIMESPAN', $timespan) : '').'
    '; + break; + } + + // Trigger onJoomBeforeUpload + $plugins = $this->_mainframe->triggerEvent('onJoomBeforeUpload'); + if(in_array(false, $plugins, true)) + { + continue; + } + + $screenshot = $images['tmp_name'][$i]; + $origfilename = $images['name'][$i]; + $screenshot_filesize = $images['size'][$i]; + + // Get extension + $tag = strtolower(JFile::getExt($origfilename)); + + $this->_debugoutput .= JText::sprintf('COM_JOOMGALLERY_UPLOAD_FILENAME', $origfilename).'
    '; + + // Image size must not exceed the setting in backend if we are in frontend + if($this->_site && $screenshot_filesize > $this->_config->get('jg_maxfilesize')) + { + $this->_debugoutput .= JText::sprintf('COM_JOOMGALLERY_UPLOAD_OUTPUT_MAX_ALLOWED_FILESIZE', $this->_config->get('jg_maxfilesize')).'
    '; + $this->debug = true; + continue; + } + + // Check for right format + if( (($tag != 'jpeg') && ($tag != 'jpg') && ($tag != 'jpe') && ($tag != 'gif') && ($tag != 'png')) + || strlen($screenshot) == 0 + || $screenshot == 'none' + ) + { + $this->_debugoutput .= JText::_('COM_JOOMGALLERY_UPLOAD_OUTPUT_INVALID_IMAGE_TYPE').'
    '; + $this->debug = true; + continue; + } + + $filecounter = null; + if( ($this->_site && $this->_config->get('jg_useruploadnumber')) + || + (!$this->_site && $this->_config->get('jg_filenamenumber')) + ) + { + $filecounter = $this->_getSerial(); + } + + + // Create new filename + // If generic filename set in backend use them + if( ($this->_site && $this->_config->get('jg_useruseorigfilename')) + || + (!$this->_site && $this->_config->get('jg_useorigfilename')) + ) + { + $oldfilename = $origfilename; + $newfilename = JoomFile::fixFilename($origfilename); + } + else + { + $oldfilename = $this->imgtitle; + $newfilename = JoomFile::fixFilename($this->imgtitle); + } + + // Check the new filename + if(JoomFile::checkValidFilename($oldfilename, $newfilename) == false) + { + if($this->_site) + { + $this->_debugoutput .= JText::_('COM_JOOMGALLERY_COMMON_ERROR_INVALID_FILENAME').'
    '; + } + else + { + $this->_debugoutput .= JText::sprintf('COM_JOOMGALLERY_UPLOAD_ERROR_INVALID_FILENAME', $newfilename, $oldfilename).'
    '; + } + $this->debug = true; + continue; + } + + $newfilename = $this->_genFilename($newfilename, $tag, $filecounter); + + // We'll assume that this file is ok because with open_basedir, + // we can move the file, but may not be able to access it until it's moved + $return = JFile::upload($screenshot, $this->_ambit->getImg('orig_path', $newfilename, null, $this->catid)); + if(!$return) + { + $this->_debugoutput .= JText::sprintf('COM_JOOMGALLERY_UPLOAD_ERROR_UPLOADING', $this->_ambit->getImg('orig_path', $newfilename, null, $this->catid)).'
    '; + $this->debug = true; + continue; + } + + $this->_debugoutput .= JText::_('COM_JOOMGALLERY_UPLOAD_OUTPUT_UPLOAD_COMPLETE').'
    '; + + // Set permissions of uploaded file + $return = JoomFile::chmod($this->_ambit->getImg('orig_path', $newfilename, null, $this->catid), '0644'); + /*if(!$return) + { + $this->_debugoutput .= $this->_ambit->getImg('orig_path', $newfilename, null, $this->catid).' '.JText::_('COM_JOOMGALLERY_COMMON_CHECK_PERMISSIONS').'
    '; + $this->rollback($this->_ambit->getImg('orig_path', $newfilename, null, $this->catid), + null, + null + ); + $this->debug = true; + continue; + }*/ + + // Create thumbnail and detail image + if(!$this->resizeImage($this->_ambit->getImg('orig_path', $newfilename, null, $this->catid), $newfilename)) + { + $this->rollback($this->_ambit->getImg('orig_path', $newfilename, null, $this->catid), + $this->_ambit->getImg('img_path', $newfilename, null, $this->catid), + $this->_ambit->getImg('thumb_path', $newfilename, null, $this->catid) + ); + $this->debug = true; + continue; + } + + // Insert database entry + $row = JTable::getInstance('joomgalleryimages', 'Table'); + if(!$this->registerImage($row, $origfilename, $newfilename, $tag, $filecounter)) + { + $this->rollback($this->_ambit->getImg('orig_path', $newfilename, null, $this->catid), + $this->_ambit->getImg('img_path', $newfilename, null, $this->catid), + $this->_ambit->getImg('thumb_path', $newfilename, null, $this->catid) + ); + $this->debug = true; + continue; + } + + // Message about new image + if($this->_site) + { + require_once JPATH_COMPONENT.'/helpers/messenger.php'; + $messenger = new JoomMessenger(); + $message = array( + 'from' => $this->_user->get('id'), + 'subject' => JText::_('COM_JOOMGALLERY_UPLOAD_MESSAGE_NEW_IMAGE_UPLOADED'), + 'body' => JText::sprintf('COM_JOOMGALLERY_MESSAGE_NEW_IMAGE_SUBMITTED_BODY', $this->_config->get('jg_realname') ? $this->_user->get('name') : $this->_user->get('username'), $row->imgtitle), + 'mode' => 'upload' + ); + $messenger->send($message); + } + + $this->_debugoutput .= JText::_('COM_JOOMGALLERY_UPLOAD_OUTPUT_IMAGE_SUCCESSFULLY_ADDED').'
    '; + $this->_debugoutput .= JText::sprintf('COM_JOOMGALLERY_UPLOAD_NEW_FILENAME', $newfilename).'

    '; + + $this->_mainframe->triggerEvent('onJoomAfterUpload', array($row)); + $this->counter++; + } + + $this->_debugoutput .= '

    '; + + // Reset file counter, delete original and create special gif selection and debug information + $this->_mainframe->setUserState('joom.upload.filecounter', 0); + $this->_mainframe->setUserState('joom.upload.delete_original', false); + $this->_mainframe->setUserState('joom.upload.create_special_gif', false); + $this->_mainframe->setUserState('joom.upload.debug', false); + $this->_mainframe->setUserState('joom.upload.debugoutput', null); + + echo $this->_debugoutput; + + if(!$this->_site || JRequest::getBool('redirect')) + { + return !$this->debug; + } + + JHTML::addIncludePath(JPATH_COMPONENT_ADMINISTRATOR.'/helpers/html'); +?> +

    + + + + +

    +

    + + + + +

    +

    + + + + +

    +debug; + } + + /** + * Extract images from zip + * + * @return boolean True on success, false otherwise. + * @since 1.0.0 + */ + protected function uploadBatch() + { + // Check access + $category = $this->getCategory($this->catid); + if( !$category + || ( !$this->_user->authorise('joom.upload', _JOOM_OPTION.'.category.'.$this->catid) + && ( !$this->_user->authorise('joom.upload.inown', _JOOM_OPTION.'.category.'.$this->catid) + || !$category->owner + || $category->owner != $this->_user->get('id') + ) + ) + ) + { + $this->setError(JText::_('COM_JOOMGALLERY_COMMON_MSG_YOU_ARE_NOT_ALLOWED_TO_UPLOAD_INTO_THIS_CATEGORY')); + + return false; + } + + // Load the refresher in order to initialise it right now at the beginning + require_once JPATH_COMPONENT_ADMINISTRATOR.'/helpers/refresher.php'; + $refresher = new JoomRefresher(); + + // Check existence of temp directory + if(!JFolder::exists($this->_ambit->get('temp_path'))) + { + $this->setError(JText::_('COM_JOOMGALLERY_UPLOAD_ERROR_TEMP_MISSING')); + + return false; + } + + // Check existence of uploaded zip + if($zippack = JRequest::getVar('zippack', '', 'files')) + { + if(!JFile::exists($zippack['tmp_name'])) + { + $this->setError(JText::_('COM_JOOMGALLERY_UPLOAD_ERROR_FILE_NOT_UPLOADED')); + return false; + } + + // Make temp path writeable if it is not, workaround for servers with wwwrun-problem + $permissions_changed = false; + if(!is_writeable($this->_ambit->get('temp_path'))) + { + JoomFile::chmod($this->_ambit->get('temp_path'), '0777', true); + $permissions_changed = true; + } + + // Create subdirectory in tmp folder + // $zippack['name'] = original name of uploaded archive + // strip extension before and add a random number at the end + $extractdir = $this->_ambit->get('temp_path') + .JFile::stripExt($zippack['name']) + .'-' + .mt_rand(10000, 99999); + + $createerr = JFolder::create($extractdir); + + // Check createerr + if(!$createerr) + { + $this->setError(JText::_('COM_JOOMGALLERY_UPLOAD_ERROR_FILE_NOT_UPLOADED')); + return false; + } + + // Move uploaded file to a new directory with original name + // because the uploaded archive is saved like php8900.tmp and JArchive + // needs a valid extension + $zipfile = $extractdir.'/'.$zippack['name']; + JFile::upload($zippack['tmp_name'], $zipfile); + + // Extract archive to new directory, JArchive chooses the right adapter + // according to the extension + jimport('joomla.filesystem.archive'); + $extracterr = JArchive::extract($zipfile, $extractdir); + + // TODO LF constant - Check error code of extraction + if(!$extracterr) + { + $this->setError(JText::_('COM_JOOMGALLERY_UPLOAD_ERROR_FILE_NOT_UPLOADED')); + return false; + } + + // Get all files from extraction directory with the allowed + // extension, recursively, with full path + $inclusions = '.jpg$|.JPG$|.jpeg$|.JPEG$|.jpe$|.JPE$|.png$|.PNG$|.gif$|.GIF$'; + $ziplist = JFolder::files($extractdir, $inclusions, true, true); + + // Set back temp path permissions if they were changed before + if($permissions_changed) + { + JoomFile::chmod($this->_ambit->get('temp_path'), '0755', true); + } + + $sizeofzip = count($ziplist); + + // For each file extracted from zip get original filename and create + // unique filename. Copy to new location, delete file in temp. location, + // make thumbnail and add to database + $this->_debugoutput .= '


    '; + if($sizeofzip == 1) + { + $this->_debugoutput .= JText::_('COM_JOOMGALLERY_UPLOAD_OUTPUT_FILE_IN_BATCH'); + } + else + { + $this->_debugoutput .= JText::sprintf('COM_JOOMGALLERY_UPLOAD_OUTPUT_FILES_IN_BATCH', $sizeofzip); + } + + natcasesort($ziplist); + + $start = true; + + // Set session for extractdir in case of refreshing and deleting at end + $this->_mainframe->setUserState('joom.upload.batch.subdir', $extractdir); + } + else + { + $ziplist = $this->_mainframe->getUserState('joom.upload.batch.files'); + $sizeofzip = count($ziplist); + $start = false; + } + + // Counter of successfully uploaded images + $counter = $this->_mainframe->getUserState('joom.upload.batch.counter', 0); + + // Reset the refresher in order to set total count of images to process + $refresher->reset($sizeofzip, $start); + + foreach($ziplist as $key => $file) + { + // Check remaining time + if(!$refresher->check()) + { + $this->_mainframe->setUserState('joom.upload.batch.files', $ziplist); + //$this->_mainframe->setUserState('joom.upload.debugoutput', $this->_debugoutput); + $this->_mainframe->setUserState('joom.upload.debug', $this->debug); + $this->_mainframe->setUserState('joom.upload.batch.counter', $counter); + $refresher->refresh(count($ziplist)); + } + + if($this->_site && $this->counter > $this->_config->get('jg_maxuserimage') - 1 && $this->_user->get('id')) + { + $timespan = $this->_config->get('jg_maxuserimage_timespan'); + $this->_debugoutput .= '
    '.JText::sprintf('COM_JOOMGALLERY_UPLOAD_OUTPUT_MAY_ADD_MAX_OF', $this->_config->get('jg_maxuserimage'), $timespan > 0 ? JText::plural('COM_JOOMGALLERY_UPLOAD_NEW_IMAGE_MAXCOUNT_TIMESPAN', $timespan) : '').'
    '; + break; + } + + // Trigger event 'onJoomBeforeUpload' + $plugins = $this->_mainframe->triggerEvent('onJoomBeforeUpload'); + if(in_array(false, $plugins, true)) + { + unset($ziplist[$key]); + continue; + } + + // Get the filename without path, JFile::getName() does not + // work on local installations + $filepathinfos = pathinfo($file); + $origfilename = $filepathinfos['basename']; + $filesize = filesize($file); + $tag = strtolower(JFile::getExt($origfilename)); + + $this->_debugoutput .= '
    '; + $this->_debugoutput .= JText::sprintf('COM_JOOMGALLERY_UPLOAD_FILENAME', $origfilename).'
    '; + + // Image size must not exceed the setting in backend if we are in frontend + if($this->_site && $filesize > $this->_config->get('jg_maxfilesize')) + { + $this->_debugoutput .= JText::sprintf('COM_JOOMGALLERY_UPLOAD_OUTPUT_MAX_ALLOWED_FILESIZE', $this->_config->get('jg_maxfilesize')).'
    '; + $this->debug = true; + unset($ziplist[$key]); + continue; + } + + // Check for right format + if( (($tag != 'jpeg') && ($tag != 'jpg') && ($tag != 'jpe') && ($tag != 'gif') && ($tag != 'png')) + || strlen($file) == 0 + || $file == 'none' + ) + { + $this->_debugoutput .= JText::_('COM_JOOMGALLERY_UPLOAD_OUTPUT_INVALID_IMAGE_TYPE').'
    '; + $this->debug = true; + unset($ziplist[$key]); + continue; + } + + // Check filename for special characters if not allowed + if($this->_config->get('jg_filenamewithjs') == 0) + { + if( ($this->_site && $this->_config->get('jg_useruseorigfilename')) + || + (!$this->_site && $this->_config->get('jg_useorigfilename')) + ) + { + $filename = $origfilename; + } + else + { + $filename = $this->imgtitle; + } + + if(JoomFile::checkValidFilename($filename, '', true) == false) + { + if($this->_site) + { + $this->_debugoutput .= JText::_('COM_JOOMGALLERY_COMMON_ERROR_INVALID_FILENAME').'
    '; + } + else + { + $this->_debugoutput .= JText::_('COM_JOOMGALLERY_UPLOAD_ERROR_INVALIDSC_FILENAME').'
    '; + } + $this->debug = true; + unset($ziplist[$key]); + continue; + } + } + + // Get the serial number if numbering is activated + $filecounter = null; + if( ($this->_site && $this->_config->get('jg_useruploadnumber')) + || + (!$this->_site && $this->_config->get('jg_filenamenumber')) + ) + { + $filecounter = $this->_getSerial(); + } + + // Create new filename + // If generic filename set in backend use it + if( ($this->_site && $this->_config->get('jg_useruseorigfilename')) + || + (!$this->_site && $this->_config->get('jg_useorigfilename')) + ) + { + $oldfilename = $origfilename; + $newfilename = JoomFile::fixFilename($origfilename); + } + else + { + $oldfilename = $this->imgtitle; + $newfilename = JoomFile::fixFilename($this->imgtitle); + } + + // Check the new filename + if(JoomFile::checkValidFilename($oldfilename, $newfilename) == false) + { + if($this->_site) + { + $this->_debugoutput .= JText::_('COM_JOOMGALLERY_COMMON_ERROR_INVALID_FILENAME').'
    '; + } + else + { + $this->_debugoutput .= JText::sprintf('COM_JOOMGALLERY_UPLOAD_ERROR_INVALID_FILENAME', $newfilename, $oldfilename).'
    '; + } + $this->debug = true; + unset($ziplist[$key]); + continue; + } + + $newfilename = $this->_genFilename($newfilename, $tag, $filecounter); + + // Move the image from temp folder to originals folder + $return = JFile::move($file, + $this->_ambit->getImg('orig_path', $newfilename, null, $this->catid)); + if(!$return) + { + $this->_debugoutput .= JText::sprintf('COM_JOOMGALLERY_UPLOAD_OUTPUT_PROBLEM_MOVING', $this->_ambit->getImg('orig_path', $newfilename, null, $this->catid)).' '.JText::_('COM_JOOMGALLERY_COMMON_CHECK_PERMISSIONS').'
    '; + $this->debug = true; + unset($ziplist[$key]); + continue; + } + + // Try to set permissions to 644 + $return = JoomFile::chmod($this->_ambit->getImg('orig_path', $newfilename, null, $this->catid), '0644'); + + $this->_debugoutput .= JText::_('COM_JOOMGALLERY_UPLOAD_OUTPUT_UPLOAD_COMPLETE').'
    '; + + // Create thumbnail and detail image + if(!$this->resizeImage($this->_ambit->getImg('orig_path', $newfilename, null, $this->catid), $newfilename)) + { + $this->rollback($this->_ambit->getImg('orig_path', $newfilename, null, $this->catid), + $this->_ambit->getImg('img_path', $newfilename, null, $this->catid), + $this->_ambit->getImg('thumb_path', $newfilename, null, $this->catid) + ); + $this->debug = true; + unset($ziplist[$key]); + continue; + } + + // Insert the database entry + $row = JTable::getInstance('joomgalleryimages', 'Table'); + if(!$this->registerImage($row, $origfilename, $newfilename, $tag, $filecounter)) + { + $this->rollback($this->_ambit->getImg('orig_path', $newfilename, null, $this->catid), + $this->_ambit->getImg('img_path', $newfilename, null, $this->catid), + $this->_ambit->getImg('thumb_path', $newfilename, null, $this->catid) + ); + $this->debug = true; + unset($ziplist[$key]); + continue; + } + + $this->_debugoutput .= JText::_('COM_JOOMGALLERY_UPLOAD_OUTPUT_IMAGE_SUCCESSFULLY_ADDED').'
    '; + $this->_debugoutput .= JText::sprintf('COM_JOOMGALLERY_UPLOAD_NEW_FILENAME', $newfilename).'

    '; + + $counter++; + + $this->_mainframe->triggerEvent('onJoomAfterUpload', array($row)); + + $this->counter++; + + unset($ziplist[$key]); + } + + // Remove subdir in temp finally + $tempdir = $this->_mainframe->getUserState('joom.upload.batch.subdir'); + if($tempdir) + { + JFolder::delete($tempdir); + } + + // Message about new images + if($this->_site && $counter) + { + require_once(JPATH_COMPONENT.'/helpers/messenger.php'); + $messenger = new JoomMessenger(); + $message = array( + 'from' => $this->_user->get('id'), + 'subject' => JText::_('COM_JOOMGALLERY_MESSAGE_NEW_IMAGES_SUBMITTED_SUBJECT'), + 'body' => JText::sprintf('COM_JOOMGALLERY_MESSAGE_NEW_IMAGES_SUBMITTED_BODY', $this->_config->get('jg_realname') ? $this->_user->get('name') : $this->_user->get('username'), $counter), + 'mode' => 'upload' + ); + $messenger->send($message); + } + + $this->_debugoutput .= '

    '; + + // Reset file counters, delete original and create special gif selection and debug information + $this->_mainframe->setUserState('joom.upload.filecounter', 0); + $this->_mainframe->setUserState('joom.upload.batch.counter', 0); + $this->_mainframe->setUserState('joom.upload.delete_original', false); + $this->_mainframe->setUserState('joom.upload.create_special_gif', false); + $this->_mainframe->setUserState('joom.upload.debug', false); + $this->_mainframe->setUserState('joom.upload.debugoutput', null); + + echo $this->_debugoutput; + + if(!$this->_site || JRequest::getBool('redirect')) + { + return !$this->debug; + } + + JHTML::addIncludePath(JPATH_COMPONENT_ADMINISTRATOR.'/helpers/html'); +?> +

    + + + + +

    +

    + + + + +

    +

    + + + + +

    +debug; + } + + /** + * JAVA Applet upload + * + * @return void + * @since 1.0.0 + */ + protected function uploadJava() + { + + // The Applet recognize an error with the text 'JOOMGALLERYUPLOADERROR' + // and shows them within an JS alert box + + // Check common requirements + // No catid + if(!$this->catid) + { + jexit('JOOMGALLERYUPLOADERROR '.JText::_('COM_JOOMGALLERY_UPLOAD_JUPLOAD_SELECT_CATEGORY')); + } + + // No common title + if( (!$this->_site || !$this->_config->get('jg_useruseorigfilename')) + && ($this->_site || !$this->_config->get('jg_useorigfilename')) + && !JRequest::getVar('imgtitle', '', 'post') + ) + { + jexit('JOOMGALLERYUPLOADERROR '.JText::_('COM_JOOMGALLERY_UPLOAD_JUPLOAD_IMAGE_MUST_HAVE_TITLE')); + } + + // Access check + $category = $this->getCategory($this->catid); + if( !$category + || ( !$this->_user->authorise('joom.upload', _JOOM_OPTION.'.category.'.$this->catid) + && ( !$this->_user->authorise('joom.upload.inown', _JOOM_OPTION.'.category.'.$this->catid) + || !$category->owner + || $category->owner != $this->_user->get('id') + ) + ) + ) + { + jexit('JOOMGALLERYUPLOADERROR '.JText::_('COM_JOOMGALLERY_COMMON_MSG_YOU_ARE_NOT_ALLOWED_TO_UPLOAD_INTO_THIS_CATEGORY')); + } + + $images = $_FILES; + + foreach($images as $file => $fileArray) + { + if($this->_site && $this->counter > $this->_config->get('jg_maxuserimage') - 1 && $this->_user->get('id')) + { + $timespan = $this->_config->get('jg_maxuserimage_timespan'); + $this->_debugoutput .= JText::sprintf('COM_JOOMGALLERY_UPLOAD_OUTPUT_MAY_ADD_MAX_OF', $this->_config->get('jg_maxuserimage'), $timespan > 0 ? JText::plural('COM_JOOMGALLERY_UPLOAD_NEW_IMAGE_MAXCOUNT_TIMESPAN', $timespan) : ''); + $this->debug = true; + break; + } + + // Check error codes + if($fileArray['error'] > 0) + { + $this->_debugoutput .= $this->checkError($fileArray['error']).'\n'; + $this->debug = true; + continue; + } + + // Trigger event 'onJoomBeforeUpload' + $plugins = $this->_mainframe->triggerEvent('onJoomBeforeUpload'); + if(in_array(false, $plugins, true)) + { + $this->_debugoutput .= 'Upload was stopped by a plugin'; + $this->debug = true; + continue; + } + + $screenshot = $fileArray['tmp_name']; + $origfilename = $fileArray['name']; + $screenshot_filesize = $fileArray['size']; + + // Get extension + $tag = strtolower(JFile::getExt($origfilename)); + + $this->_debugoutput .= JText::sprintf('COM_JOOMGALLERY_UPLOAD_FILENAME', $origfilename).'\n'; + + // Check filename for special characters if not allowed + if($this->_config->get('jg_filenamewithjs') == 0) + { + if( ($this->_site && $this->_config->get('jg_useruseorigfilename')) + || + (!$this->_site && $this->_config->get('jg_useorigfilename')) + ) + { + $filename = $origfilename; + } + else + { + $filename = $this->imgtitle; + } + + if(JoomFile::checkValidFilename($filename, '', true) == false) + { + if($this->_site) + { + $this->_debugoutput .= strip_tags(JText::_('COM_JOOMGALLERY_COMMON_ERROR_INVALID_FILENAME')); + } + else + { + $this->_debugoutput .= strip_tags(JText::_('COM_JOOMGALLERY_UPLOAD_ERROR_INVALIDSC_FILENAME')); + } + $this->debug = true; + continue; + } + } + + // Image size must not exceed the setting in backend except if we are in frontend + if($this->_site && $screenshot_filesize > $this->_config->get('jg_maxfilesize')) + { + $this->_debugoutput .= JText::sprintf('COM_JOOMGALLERY_UPLOAD_OUTPUT_MAX_ALLOWED_FILESIZE', $this->_config->get('jg_maxfilesize')).'\n'; + $this->debug = true; + continue; + } + + // Check for right format + if( (($tag != 'jpeg') && ($tag != 'jpg') && ($tag != 'jpe') && ($tag != 'gif') && ($tag != 'png')) + || strlen($screenshot) == 0 + || $screenshot == 'none' + ) + { + $this->_debugoutput .= JText::_('COM_JOOMGALLERY_UPLOAD_OUTPUT_INVALID_IMAGE_TYPE').'\n'; + $this->debug = true; + continue; + } + + $filecounter = null; + + // Create new filename + // If generic filename set in backend use them + if( ($this->_site && $this->_config->get('jg_useruseorigfilename')) + || + (!$this->_site && $this->_config->get('jg_useorigfilename')) + ) + { + $oldfilename = $origfilename; + $newfilename = JoomFile::fixFilename($origfilename); + } + else + { + $oldfilename = $this->imgtitle; + $newfilename = JoomFile::fixFilename($this->imgtitle); + } + + // Check the new filename + if(JoomFile::checkValidFilename($oldfilename, $newfilename) == false) + { + if($this->_site) + { + $this->_debugoutput .= strip_tags(JText::_('COM_JOOMGALLERY_COMMON_ERROR_INVALID_FILENAME')); + } + else + { + $this->_debugoutput .= strip_tags(JText::sprintf('COM_JOOMGALLERY_UPLOAD_ERROR_INVALID_FILENAME', $newfilename, $oldfilename)); + } + $this->debug = true; + continue; + } + + $newfilename = $this->_genFilename($newfilename, $tag, $filecounter); + + // If 'delete originals' is chosen in backend and the image + // shall be uploaded resized this will be done locally in the applet. + // Then, only the detail image will be uploaded. + if( + $this->_config->get('jg_resizetomaxwidth') + && + ( ($this->_site && $this->_config->get('jg_delete_original_user') == 1) + || (!$this->_site && $this->_config->get('jg_delete_original') == 1) + ) + ) + { + // Upload image to detail images folder + $return = JFile::upload($screenshot, $this->_ambit->getImg('img_path', $newfilename, null, $this->catid)); + if(!$return) + { + $this->_debugoutput .= JText::_('COM_JOOMGALLERY_UPLOAD_ERROR_UPLOADING', $this->_ambit->getImg('img_path', $newfilename, null, $this->catid)); + $this->debug = true; + continue; + } + + $return = JoomFile::chmod($this->_ambit->getImg('img_path', $newfilename, null, $this->catid), '0644'); + /*if(!$return) + { + $this->_debugoutput .= $this->_ambit->getImg('img_path', $newfilename, null, $this->catid).' '.JText::_('COM_JOOMGALLERY_COMMON_CHECK_PERMISSIONS').'\n'; + $this->rollback(null, + $this->_ambit->getImg('img_path', $newfilename, null, $this->catid), + null + ); + $this->debug = true; + continue; + }*/ + + // Create thumbnail + $return = JoomFile::resizeImage($this->_debugoutput, + $this->_ambit->getImg('img_path', $newfilename, null, $this->catid), + $this->_ambit->getImg('thumb_path', $newfilename, null, $this->catid), + $this->_config->get('jg_useforresizedirection'), + $this->_config->get('jg_thumbwidth'), + $this->_config->get('jg_thumbheight'), + $this->_config->get('jg_thumbcreation'), + $this->_config->get('jg_thumbquality'), + false, + $this->_config->get('jg_cropposition') + ); + if(!$return) + { + $this->_debugoutput .= JText::sprintf('COM_JOOMGALLERY_UPLOAD_OUTPUT_THUMBNAIL_NOT_CREATED', $this->_ambit->getImg('thumb_path', $newfilename, null, $this->catid)).'\n'; + $this->rollback(null, + $this->_ambit->getImg('img_path', $newfilename, null, $this->catid), + $this->_ambit->getImg('thumb_path', $newfilename, null, $this->catid) + ); + $this->debug = true; + continue; + } + $this->_debugoutput .= JText::_('COM_JOOMGALLERY_UPLOAD_OUTPUT_THUMBNAIL_CREATED').'
    '; + } + else + { + // Upload image into original images folder + $return = JFile::upload($screenshot, $this->_ambit->getImg('orig_path', $newfilename, null, $this->catid)); + if(!$return) + { + $this->_debugoutput .= JText::_('COM_JOOMGALLERY_UPLOAD_ERROR_UPLOADING', $this->_ambit->getImg('orig_path', $newfilename, null, $this->catid)).'\n'; + $this->debug = true; + continue; + } + + $return = JoomFile::chmod($this->_ambit->getImg('orig_path', $newfilename, null, $this->catid), '0644'); + /*if(!$return) + { + $this->_debugoutput .= $this->_ambit->getImg('orig_path', $newfilename, null, $this->catid).' '.JText::_('COM_JOOMGALLERY_COMMON_CHECK_PERMISSIONS').'\n'; + $this->rollback($this->_ambit->getImg('orig_path', $newfilename, null, $this->catid), + null, + null + ); + $this->debug = true; + continue; + }*/ + + // Create thumbnail and detail image + if(!$this->resizeImage($this->_ambit->getImg('orig_path', $newfilename, null, $this->catid), $newfilename)) + { + $this->rollback($this->_ambit->getImg('orig_path', $newfilename, null, $this->catid), + $this->_ambit->getImg('img_path', $newfilename, null, $this->catid), + $this->_ambit->getImg('thumb_path', $newfilename, null, $this->catid) + ); + $this->debug = true; + continue; + } + } + + // Insert the database entry + $row = JTable::getInstance('joomgalleryimages', 'Table'); + if(!$this->registerImage($row, $origfilename, $newfilename, $tag)) + { + $this->rollback($this->_ambit->getImg('orig_path', $newfilename, null, $this->catid), + $this->_ambit->getImg('img_path', $newfilename, null, $this->catid), + $this->_ambit->getImg('thumb_path', $newfilename, null, $this->catid) + ); + $this->debug = true; + continue; + } + + $this->_debugoutput .= JText::_('COM_JOOMGALLERY_UPLOAD_OUTPUT_IMAGE_SUCCESSFULLY_ADDED').'\n'; + $this->_debugoutput .= JText::sprintf('COM_JOOMGALLERY_UPLOAD_NEW_FILENAME', $newfilename).'\n'; + + $this->_mainframe->triggerEvent('onJoomAfterUpload', array($row)); + $this->counter++; + } + + // Reset file counter, delete original and create special gif selection and debug information + $this->_mainframe->setUserState('joom.upload.filecounter', 0); + $this->_mainframe->setUserState('joom.upload.delete_original', false); + $this->_mainframe->setUserState('joom.upload.create_special_gif', false); + $this->_mainframe->setUserState('joom.upload.debug', false); + $this->_mainframe->setUserState('joom.upload.debugoutput', null); + + if($this->debug) + { + echo "JOOMGALLERYUPLOADERROR "; + } + else + { + // Counter of successfully uploaded images, only in frontend upload + if($this->_site) + { + $counter = $this->_mainframe->getUserState('joom.upload.java.counter', 0); + $counter++; + $this->_mainframe->setUserState('joom.upload.java.counter', $counter); + } + echo "\nJOOMGALLERYUPLOADSUCCESS\n"; + } + + echo $this->_debugoutput; + + jexit(); + } + + /** + * FTP Upload + * Several images uploaded via FTP before are moved to a category + * + * @return void + * @since 1.0.0 + */ + protected function uploadFTP() + { + // FTP upload is only available in backend at the moment + if($this->_site) + { + return false; + } + + // Access check + $category = $this->getCategory($this->catid); + if( !$category + || ( !$this->_user->authorise('joom.upload', _JOOM_OPTION.'.category.'.$this->catid) + && ( !$this->_user->authorise('joom.upload.inown', _JOOM_OPTION.'.category.'.$this->catid) + || !$category->owner + || $category->owner != $this->_user->get('id') + ) + ) + ) + { + $this->setError(JText::_('COM_JOOMGALLERY_COMMON_MSG_YOU_ARE_NOT_ALLOWED_TO_UPLOAD_INTO_THIS_CATEGORY')); + + return false; + } + + $subdirectory = $this->_db->escape($this->_mainframe->getUserStateFromRequest('joom.upload.ftp.subdirectory', 'subdirectory', '/', 'post', 'string')); + $ftpfiles = $this->_mainframe->getUserStateFromRequest('joom.upload.ftp.files', 'ftpfiles', array(), 'array'); + + if(!$ftpfiles && JRequest::getBool('ftpfiles')) + { + $this->setError(JText::_('COM_JOOMGALLERY_COMMON_MSG_NO_IMAGES_SELECTED')); + + return false; + } + + // Load the refresher + require_once JPATH_COMPONENT.'/helpers/refresher.php'; + $refresher = new JoomRefresher(array('remaining' => count($ftpfiles), 'start' => JRequest::getBool('ftpfiles'))); + + $this->_debugoutput .= '

    '; + + foreach($ftpfiles as $key => $origfilename) + { + // Check remaining time + if(!$refresher->check()) + { + $this->_mainframe->setUserState('joom.upload.ftp.files', $ftpfiles); + //$this->_mainframe->setUserState('joom.upload.debugoutput', $this->_debugoutput); + $this->_mainframe->setUserState('joom.upload.debug', $this->debug); + $refresher->refresh(count($ftpfiles)); + } + + // Get extension + $tag = strtolower(JFile::getExt($origfilename)); + + $this->_debugoutput .= '
    '; + $this->_debugoutput .= JText::sprintf('COM_JOOMGALLERY_UPLOAD_FILENAME', $origfilename).'
    '; + + /*// Image size must not exceed the setting in backend if we are in frontend + if($this->_site && $screenshot_filesize > $this->_config->get('jg_maxfilesize')) + { + $this->_debugoutput .= JText::sprintf('COM_JOOMGALLERY_UPLOAD_OUTPUT_MAX_ALLOWED_FILESIZE', $this->_config->get('jg_maxfilesize')).'
    '; + $this->debug = true; + unset($ftpfiles[$key]); + continue; + }*/ + + // Check for right format + if( (($tag != 'jpeg') && ($tag != 'jpg') && ($tag != 'jpe') && ($tag != 'gif') && ($tag != 'png')) + || strlen($origfilename) == 0 + ) + { + $this->_debugoutput .= JText::_('COM_JOOMGALLERY_UPLOAD_OUTPUT_INVALID_IMAGE_TYPE').'
    '; + $this->debug = true; + unset($ftpfiles[$key]); + continue; + } + + // Check filename for special characters if not allowed + if($this->_config->get('jg_filenamewithjs') == 0) + { + if( ($this->_site && $this->_config->get('jg_useruseorigfilename')) + || + (!$this->_site && $this->_config->get('jg_useorigfilename')) + ) + { + $filename = $origfilename; + } + else + { + $filename = $this->imgtitle; + } + + if(JoomFile::checkValidFilename($filename, '', true) == false) + { + $this->_debugoutput .= strip_tags(JText::_('COM_JOOMGALLERY_UPLOAD_ERROR_INVALIDSC_FILENAME')); + $this->debug = true; + unset($ftpfiles[$key]); + continue; + } + } + + $filecounter = null; + if( ($this->_site && $this->_config->get('jg_useruploadnumber')) + || + (!$this->_site && $this->_config->get('jg_filenamenumber')) + ) + { + $filecounter = $this->_getSerial(); + } + + // Create new filename + // If generic filename set in backend use them + if( ($this->_site && $this->_config->get('jg_useruseorigfilename')) + || + (!$this->_site && $this->_config->get('jg_useorigfilename')) + ) + { + $oldfilename = $origfilename; + $newfilename = JoomFile::fixFilename($origfilename); + } + else + { + $oldfilename = $this->imgtitle; + $newfilename = JoomFile::fixFilename($this->imgtitle); + } + + // Check the new filename + if(JoomFile::checkValidFilename($oldfilename, $newfilename) == false) + { + $this->_debugoutput .= strip_tags(JText::sprintf('COM_JOOMGALLERY_UPLOAD_ERROR_INVALID_FILENAME', $newfilename, $oldfilename)); + $this->debug = true; + unset($ftpfiles[$key]); + continue; + } + + $newfilename = $this->_genFilename($newfilename, $tag, $filecounter); + + // Resize image + $delete_file = $this->_mainframe->getUserStateFromRequest('joom.upload.file_delete', 'file_delete', false, 'bool'); + if(!$this->resizeImage(JPath::clean($this->_ambit->get('ftp_path').$subdirectory.$origfilename), $newfilename, false, $delete_file)) + { + $this->rollback($this->_ambit->getImg('orig_path', $newfilename, null, $this->catid), + $this->_ambit->getImg('img_path', $newfilename, null, $this->catid), + $this->_ambit->getImg('thumb_path', $newfilename, null, $this->catid) + ); + $this->debug = true; + unset($ftpfiles[$key]); + continue; + } + + $row = JTable::getInstance('joomgalleryimages', 'Table'); + if(!$this->registerImage($row, $origfilename, $newfilename, $tag, $filecounter)) + { + $this->rollback($this->_ambit->getImg('orig_path', $newfilename, null, $this->catid), + $this->_ambit->getImg('img_path', $newfilename, null, $this->catid), + $this->_ambit->getImg('thumb_path', $newfilename, null, $this->catid) + ); + $this->debug = true; + unset($ftpfiles[$key]); + continue; + } + + $this->_debugoutput .= JText::_('COM_JOOMGALLERY_UPLOAD_OUTPUT_IMAGE_SUCCESSFULLY_ADDED').'
    '; + $this->_debugoutput .= JText::sprintf('COM_JOOMGALLERY_UPLOAD_NEW_FILENAME', $newfilename).'

    '; + + $this->_mainframe->triggerEvent('onJoomAfterUpload', array($row)); + + unset($ftpfiles[$key]); + } + + $this->_debugoutput .= '

    '; + + // Reset file counter, delete original delete source file and + // create special gif selection and debug information + $this->_mainframe->setUserState('joom.upload.filecounter', 0); + $this->_mainframe->setUserState('joom.upload.file_delete', false); + $this->_mainframe->setUserState('joom.upload.delete_original', false); + $this->_mainframe->setUserState('joom.upload.create_special_gif', false); + $this->_mainframe->setUserState('joom.upload.debug', false); + $this->_mainframe->setUserState('joom.upload.debugoutput', null); + + if($this->debug) + { + echo $this->_debugoutput; + } + + return !$this->debug; + } + + /** + * AJAX upload + * + * An image is chosen and uploaded afore. + * + * @return void + * @since 3.0 + */ + protected function uploadAJAX() + { + // Access check + $category = $this->getCategory($this->catid); + if( !$category + || ( !$this->_user->authorise('joom.upload', _JOOM_OPTION.'.category.'.$this->catid) + && ( !$this->_user->authorise('joom.upload.inown', _JOOM_OPTION.'.category.'.$this->catid) + || !$category->owner + || $category->owner != $this->_user->get('id') + ) + ) + ) + { + $this->setError(JText::_('COM_JOOMGALLERY_COMMON_MSG_YOU_ARE_NOT_ALLOWED_TO_UPLOAD_INTO_THIS_CATEGORY')); + + return false; + } + + $image = JRequest::getVar('qqfile', '', 'files'); + $qqtotalfilesize = JRequest::getInt('qqtotalfilesize', -1); + $totalParts = JRequest::getInt('qqtotalparts', 1); + $screenshot = $image['tmp_name']; + $origfilename = JRequest::getString('qqfilename', ''); + $screenshot_filesize = $image['size']; + if(empty($origfilename)) + { + $origfilename = $image['name']; + } + + // Clean up directory containing old image chunks + $this->cleanupChunks(); + + if($totalParts == 1 && $qqtotalfilesize > 0 && $screenshot_filesize != $qqtotalfilesize) + { + $this->setError(JText::_('COM_JOOMGALLERY_UPLOAD_ERROR_FILE_PARTLY_UPLOADED')); + return false; + } + + if($image['error'] > 0) + { + $errorMsg = JText::_('COM_JOOMGALLERY_AJAXUPLOAD_UPLOAD_FAILED').' '.JText::sprintf('COM_JOOMGALLERY_UPLOAD_ERROR_CODE', $image['error']); + $this->setError($errorMsg); + + return false; + } + + if($this->_site && $this->counter > $this->_config->get('jg_maxuserimage') - 1 && $this->_user->get('id')) + { + $timespan = $this->_config->get('jg_maxuserimage_timespan'); + $errorMsg = JText::sprintf('COM_JOOMGALLERY_UPLOAD_OUTPUT_MAY_ADD_MAX_OF', $this->_config->get('jg_maxuserimage'), $timespan > 0 ? JText::plural('COM_JOOMGALLERY_UPLOAD_NEW_IMAGE_MAXCOUNT_TIMESPAN', $timespan) : ''); + $this->setError($errorMsg); + return false; + } + + $cleanChunkDir = false; + // Save a chunk + if($totalParts > 1) + { + $partIndex = JRequest::getInt('qqpartindex'); + $uuid = JRequest::getVar('qquuid'); + + if(!is_writable($this->chunksFolder)) + { + $errorMsg = JText::sprintf('COM_JOOMGALLERY_AJAXUPLOAD_ERROR_CHUNKSDIR_NOTWRITABLE', $this->chunksFolder); + $this->setError($errorMsg); + return false; + } + + // Create unique target folder for chunks + $targetFolder = $this->chunksFolder.'/'.$uuid; + if(!JFolder::exists($targetFolder)) + { + if(!JFolder::create($targetFolder)) + { + return false; + } + } + + // Save chunk in target folder + $target = $targetFolder.'/'.$partIndex; + if(JFile::upload($screenshot, $target) === true) + { + // Last chunk + if(($totalParts - 1) == $partIndex) + { + $target = $targetFolder.'/'.($partIndex + 1); + $cleanChunkDir = $targetFolder; + $screenshot = $target; + $screenshot_filesize = 0; + + if($fp_target = fopen($target, 'wb')) + { + for($parts = 0; $parts < $totalParts; $parts++) + { + $fp_chunk = fopen($targetFolder.'/'.$parts, "rb"); + $screenshot_filesize += stream_copy_to_stream($fp_chunk, $fp_target); + fclose($fp_chunk); + } + fclose($fp_target); + } + else + { + // Complete image could not be created + return false; + } + } + else + { + // Another chunk will arrive later + return true; + } + } + else + { + // Chunk could not be saved + return false; + } + } + + // Trigger onJoomBeforeUpload + $plugins = $this->_mainframe->triggerEvent('onJoomBeforeUpload'); + if(in_array(false, $plugins, true)) + { + $errorMsg = JText::_('COM_JOOMGALLERY_AJAXUPLOAD_UPLOAD_FAILED'); + $this->setError($errorMsg); + return false; + } + + $this->_debugoutput = '
    '; + $this->_debugoutput .= JText::sprintf('COM_JOOMGALLERY_UPLOAD_FILENAME', $origfilename).'
    '; + + // Image size must not exceed the setting in backend if we are in frontend + if($this->_site && $screenshot_filesize > $this->_config->get('jg_maxfilesize')) + { + $errorMsg = JText::sprintf('COM_JOOMGALLERY_UPLOAD_OUTPUT_MAX_ALLOWED_FILESIZE', $this->_config->get('jg_maxfilesize')); + $this->setError($errorMsg); + $this->_debugoutput .= $errorMsg.'
    '; + $this->debug = true; + return false; + } + + // Get extension + $tag = strtolower(JFile::getExt($origfilename)); + + // Check for right format + if( (($tag != 'jpeg') && ($tag != 'jpg') && ($tag != 'jpe') && ($tag != 'gif') && ($tag != 'png')) + || strlen($screenshot) == 0 + || $screenshot == 'none' + ) + { + $errorMsg = JText::_('COM_JOOMGALLERY_UPLOAD_OUTPUT_INVALID_IMAGE_TYPE'); + $this->setError($errorMsg); + $this->_debugoutput .= $errorMsg.'
    '; + $this->debug = true; + return false; + } + + $filecounter = null; + if( ($this->_site && $this->_config->get('jg_useruploadnumber')) + || + (!$this->_site && $this->_config->get('jg_filenamenumber')) + ) + { + $filecounter = $this->_getSerial(); + } + + // Create new filename + // If generic filename set in backend use them + if( ($this->_site && $this->_config->get('jg_useruseorigfilename')) + || + (!$this->_site && $this->_config->get('jg_useorigfilename')) + ) + { + $oldfilename = $origfilename; + $newfilename = JoomFile::fixFilename($origfilename); + } + else + { + $oldfilename = $this->imgtitle; + $newfilename = JoomFile::fixFilename($this->imgtitle); + } + + // Check the new filename + if(JoomFile::checkValidFilename($oldfilename, $newfilename) == false) + { + if($this->_site) + { + $errorMsg = JText::_('COM_JOOMGALLERY_COMMON_ERROR_INVALID_FILENAME').'
    '; + } + else + { + $errorMsg = JText::sprintf('COM_JOOMGALLERY_UPLOAD_ERROR_INVALID_FILENAME', $newfilename, $oldfilename).'
    '; + } + $this->setError($errorMsg); + $this->_debugoutput .= $errorMsg.'
    '; + $this->debug = true; + return false; + } + + $newfilename = $this->_genFilename($newfilename, $tag, $filecounter); + + if($cleanChunkDir !== false) + { + $return = JFile::move($screenshot, $this->_ambit->getImg('orig_path', $newfilename, null, $this->catid)); + // Clean up chunk directory + JFolder::delete($cleanChunkDir); + } + else + { + // We'll assume that this file is ok because with open_basedir, + // we can move the file, but may not be able to access it until it's moved + $return = JFile::upload($screenshot, $this->_ambit->getImg('orig_path', $newfilename, null, $this->catid)); + } + + if(!$return) + { + $errorMsg = JText::sprintf('COM_JOOMGALLERY_UPLOAD_ERROR_UPLOADING', $this->_ambit->getImg('orig_path', $newfilename, null, $this->catid)); + $this->setError($errorMsg); + $this->_debugoutput .= $errorMsg.'
    '; + $this->debug = true; + return false; + } + + $this->_debugoutput .= JText::_('COM_JOOMGALLERY_UPLOAD_OUTPUT_UPLOAD_COMPLETE').'
    '; + + // Set permissions of uploaded file + $return = JoomFile::chmod($this->_ambit->getImg('orig_path', $newfilename, null, $this->catid), '0644'); + // if(!$return) + // { + // $this->rollback($this->_ambit->getImg('orig_path', $newfilename, null, $this->catid), null, null); + // $errorMsg = $this->_ambit->getImg('orig_path', $newfilename, null, $this->catid).' '.JText::_('COM_JOOMGALLERY_COMMON_CHECK_PERMISSIONS'); + // $this->_debugoutput .= $errorMsg.'
    '; + // $this->debug = true; + // return false; + // } + + // Create thumbnail and detail image + if(!$this->resizeImage($this->_ambit->getImg('orig_path', $newfilename, null, $this->catid), $newfilename)) + { + $this->rollback($this->_ambit->getImg('orig_path', $newfilename, null, $this->catid), + $this->_ambit->getImg('img_path', $newfilename, null, $this->catid), + $this->_ambit->getImg('thumb_path', $newfilename, null, $this->catid) + ); + $this->debug = true; + return false; + } + + // Insert database entry + $row = JTable::getInstance('joomgalleryimages', 'Table'); + if(!$this->registerImage($row, $origfilename, $newfilename, $tag, $filecounter)) + { + $this->rollback($this->_ambit->getImg('orig_path', $newfilename, null, $this->catid), + $this->_ambit->getImg('img_path', $newfilename, null, $this->catid), + $this->_ambit->getImg('thumb_path', $newfilename, null, $this->catid) + ); + $this->debug = true; + return false; + } + + // Message about new image + if($this->_site) + { + require_once JPATH_COMPONENT.'/helpers/messenger.php'; + $messenger = new JoomMessenger(); + $message = array( + 'from' => $this->_user->get('id'), + 'subject' => JText::_('COM_JOOMGALLERY_UPLOAD_MESSAGE_NEW_IMAGE_UPLOADED'), + 'body' => JText::sprintf('COM_JOOMGALLERY_MESSAGE_NEW_IMAGE_SUBMITTED_BODY', $this->_config->get('jg_realname') ? $this->_user->get('name') : $this->_user->get('username'), $row->imgtitle), + 'mode' => 'upload' + ); + $messenger->send($message); + } + + $this->_debugoutput .= JText::_('COM_JOOMGALLERY_UPLOAD_OUTPUT_IMAGE_SUCCESSFULLY_ADDED').'
    '; + $this->_debugoutput .= JText::sprintf('COM_JOOMGALLERY_UPLOAD_NEW_FILENAME', $newfilename).'
    '; + + $this->_mainframe->triggerEvent('onJoomAfterUpload', array($row)); + + // Reset file counter, delete original and create special gif selection and debug information + $this->_mainframe->setUserState('joom.upload.filecounter', 0); + $this->_mainframe->setUserState('joom.upload.delete_original', false); + $this->_mainframe->setUserState('joom.upload.create_special_gif', false); + $this->_mainframe->setUserState('joom.upload.debug', false); + $this->_mainframe->setUserState('joom.upload.debugoutput', null); + + return $row; + } + + /** + * Generates filenames + * e.g. ___. + * + * @param string $filename Original upload name e.g. 'malta.jpg' + * @param string $tag File extension e.g. 'jpg' + * @param int $filecounter Optinally a filecounter + * @return string The generated filename + * @since 1.0.0 + */ + protected function _genFilename($filename, $tag, $filecounter = null) + { + $filedate = date('Ymd'); + + // Remove filetag = $tag incl '.' + // Only if exists in filename + if(stristr($filename, $tag)) + { + $filename = substr($filename, 0, strlen($filename)-strlen($tag)-1); + } + + do + { + mt_srand(); + $randomnumber = mt_rand(1000000000, 2099999999); + + $maxlen = 255 - 2 - strlen($filedate) - strlen($randomnumber) - (strlen($tag) + 1); + if(!is_null($filecounter)) + { + $maxlen = $maxlen - (strlen($filecounter) + 1); + } + if(strlen($filename) > $maxlen) + { + $filename = substr($filename, 0, $maxlen); + } + + // New filename + if(is_null($filecounter)) + { + $newfilename = $filename.'_'.$filedate.'_'.$randomnumber.'.'.$tag; + } + else + { + $newfilename = $filename.'_'.$filecounter.'_'.$filedate.'_'.$randomnumber.'.'.$tag; + } + } + while( JFile::exists($this->_ambit->getImg('orig_path', $newfilename, null, $this->catid)) + || JFile::exists($this->_ambit->getImg('img_path', $newfilename, null, $this->catid)) + || JFile::exists($this->_ambit->getImg('thumb_path', $newfilename, null, $this->catid)) + ); + + return $newfilename; + } + + /** + * Calculates the serial number for images file names and titles + * + * @return int New serial number + * @since 1.0.0 + */ + protected function _getSerial() + { + static $picserial; + + // Check if the initial value is already calculated + if(isset($picserial)) + { + $picserial++; + + // Store the next value in the session + $this->_mainframe->setUserState('joom.upload.filecounter', $picserial + 1); + + return $picserial; + } + + // Start value set in backend + $filecounter = $this->_mainframe->getUserStateFromRequest('joom.upload.filecounter', 'filecounter', 0, 'post', 'int'); + + // If there is no starting value set, disable numbering + if(!$filecounter) + { + return null; + } + + // No negative starting value + if($filecounter < 0) + { + $picserial = 1; + } + else + { + $picserial = $filecounter; + } + + return $picserial; + } + + /** + * Sets new ordering according to $config->jg_uploadorder + * + * @param object $row Holds the data of the new image + * @return int The new ordering number + * @since 1.0.0 + */ + protected function _getOrdering($row) + { + switch($this->_config->get('jg_uploadorder')) + { + case 1: + $ordering = $row->getPreviousOrder('catid = '.$row->catid); + break; + case 2: + $ordering = $row->getNextOrder('catid = '.$row->catid); + break; + default; + $ordering = 1; + break; + } + + return $ordering; + } + + /** + * Calculates whether the memory limit is enough + * to work on a specific image. + * + * @param string $filename The filename of the image and the path to it. + * @param string $format The image file type (e.g. 'gif', 'jpg' or 'png') + * @return boolean True, if we have enough memory to work, false otherwise + * @since 1.0.0 + */ + protected function checkMemory($filename, $format) + { + if($this->_config->get('jg_thumbcreation') == 'im') + { + // ImageMagick isn't dependent on memory_limit + return true; + } + + if((function_exists('memory_get_usage')) && (ini_get('memory_limit'))) + { + $imageInfo = getimagesize($filename); + $jpgpic = false; + switch(strtoupper($format)) + { + case 'GIF': + // Measured factor 1 is better + $channel = 1; + break; + case 'JPG': + case 'JPEG': + case 'JPE': + $channel = $imageInfo['channels']; + $jpgpic=true; + break; + case 'PNG': + // No channel for png + $channel = 3; + break; + } + $MB = 1048576; + $K64 = 65536; + + if($this->_config->get('jg_fastgd2thumbcreation') && $jpgpic && $this->_config->get('jg_thumbcreation') == 'gd2') + { + // Function of fast gd2 creation needs more memory + $corrfactor = 2.1; + } + else + { + $corrfactor = 1.7; + } + + $memoryNeeded = round(($imageInfo[0] + * $imageInfo[1] + * $imageInfo['bits'] + * $channel / 8 + + $K64) + * $corrfactor); + + $memoryNeeded = memory_get_usage() + $memoryNeeded; + // Get memory limit + $memory_limit = @ini_get('memory_limit'); + if(!empty($memory_limit) && $memory_limit != 0) + { + $memory_limit = substr($memory_limit, 0, -1) * 1024 * 1024; + } + + if($memory_limit != 0 && $memoryNeeded > $memory_limit) + { + $memoryNeededMB = round ($memoryNeeded / 1024 / 1024, 0); + $this->_debugoutput .= JText::_('COM_JOOMGALLERY_UPLOAD_OUTPUT_ERROR_MEM_EXCEED'). + $memoryNeededMB." MByte (" + .$memoryNeeded.") Serverlimit: " + .$memory_limit/$MB."MByte (".$memory_limit.")
    " ; + return false; + } + } + + return true; + } + + /** + * Rollback an erroneous upload + * + * @param string $original Path to original image + * @param string $detail Path to detail image + * @param string $thumb Path to thumbnail + * @return void + * @since 1.0.0 + */ + protected function rollback($original, $detail, $thumb) + { + if(!is_null($original) && JFile::exists($original)) + { + $return = JFile::delete($original); + if($return) + { + $this->_debugoutput .= '

    '.JText::_('COM_JOOMGALLERY_UPLOAD_OUTPUT_RB_ORGDEL_OK').'

    '; + } + else + { + $this->_debugoutput .= '

    '.JText::_('COM_JOOMGALLERY_UPLOAD_OUTPUT_RB_ORGDEL_NOK').'

    '; + } + } + + if(!is_null($detail) && JFile::exists($detail)) + { + $return = JFile::delete($detail); + if($return) + { + $this->_debugoutput .= '

    '.JText::_('COM_JOOMGALLERY_UPLOAD_OUTPUT_RB_DTLDEL_OK').'

    '; + } + else + { + $this->_debugoutput .= '

    '.JText::_('COM_JOOMGALLERY_UPLOAD_OUTPUT_RB_DTLDEL_NOK').'

    '; + } + } + + if(!is_null($thumb) && JFile::exists($thumb)) + { + $return = JFile::delete($thumb); + if($return) + { + $this->_debugoutput .= '

    '.JText::_('COM_JOOMGALLERY_UPLOAD_OUTPUT_RB_THBDEL_OK').'

    '; + } + else + { + $this->_debugoutput .= '

    '.JText::_('COM_JOOMGALLERY_UPLOAD_OUTPUT_RB_THBDEL_NOK').'

    '; + } + } + } + /** + * Returns the number of images of the current user + * + * @return int The number of images of the current user + * @since 1.5.5 + */ + protected function getImageNumber() + { + $query = $this->_db->getQuery(true) + ->select('COUNT(id)') + ->from(_JOOM_TABLE_IMAGES) + ->where('owner = '.$this->_user->get('id')); + + $timespan = $this->_config->get('jg_maxuserimage_timespan'); + if($timespan > 0) + { + $query->where('imgdate > (UTC_TIMESTAMP() - INTERVAL '. $timespan .' DAY)'); + } + + $this->_db->setQuery($query); + + return $this->_db->loadResult(); + } + + /** + * Creates thumbnail and detail image for an image file + * + * @param string $source The source file for which the thumbnail and the detail image shall be created + * @param string $filename The file name for the created files + * @param boolean $is_in_original Determines whether the source file is already in the original images folders + * @param boolean $delete_source Determines whether the source file shall be deleted after the procedure + * @return boolean True on success, false otherwise + * @since 1.5.7 + */ + protected function resizeImage($source, $filename, $is_in_original = true, $delete_source = false) + { + if(!getimagesize($source)) + { + // getimagesize didn't find a valid image + $this->_debugoutput .= JText::_('COM_JOOMGALLERY_UPLOAD_OUTPUT_INVALID_IMAGE_FILE').'
    '; + $this->debug = true; + return false; + } + + // Check the possible available memory for image resizing. + // If not available echo error message and return false + $tag = JFile::getExt($source); + if(!$this->checkMemory($source, $tag)) + { + $this->debug = true; + return false; + } + + // Create thumb + $return = JoomFile::resizeImage($this->_debugoutput, + $source, + $this->_ambit->getImg('thumb_path', $filename, null, $this->catid), + $this->_config->get('jg_useforresizedirection'), + $this->_config->get('jg_thumbwidth'), + $this->_config->get('jg_thumbheight'), + $this->_config->get('jg_thumbcreation'), + $this->_config->get('jg_thumbquality'), + false, + $this->_config->get('jg_cropposition') + ); + if(!$return) + { + $this->_debugoutput .= JText::sprintf('COM_JOOMGALLERY_UPLOAD_OUTPUT_THUMBNAIL_NOT_CREATED', $this->_ambit->getImg('thumb_path', $filename, null, $this->catid)).'
    '; + $this->debug = true; + return false; + } + $this->_debugoutput .= JText::_('COM_JOOMGALLERY_UPLOAD_OUTPUT_THUMBNAIL_CREATED').'
    '; + + // Optionally create detail image + $detail_image_created = false; + if( + $this->_config->get('jg_resizetomaxwidth') + && + ( + ($this->_site && $this->_config->get('jg_special_gif_upload') == 0) + || !$this->_mainframe->getUserStateFromRequest('joom.upload.create_special_gif', 'create_special_gif', false, 'bool') + || ($tag != 'gif' && $tag != 'png') + ) + ) + { + $return = JoomFile::resizeImage($this->_debugoutput, + $source, + $this->_ambit->getImg('img_path', $filename, null, $this->catid), + false, + $this->_config->get('jg_maxwidth'), + false, + $this->_config->get('jg_thumbcreation'), + $this->_config->get('jg_picturequality'), + true, + 0 + ); + if(!$return) + { + $this->_debugoutput .= JText::sprintf('COM_JOOMGALLERY_UPLOAD_OUTPUT_IMG_NOT_CREATED', $this->_ambit->getImg('img_path', $filename, null, $this->catid)).'
    '; + $this->debug = true; + return false; + } + + $this->_debugoutput .= JText::_('COM_JOOMGALLERY_UPLOAD_OUTPUT_RESIZED_TO_MAXWIDTH').'
    '; + $detail_image_created = true; + } + + $delete_original = $this->_mainframe->getUserStateFromRequest('joom.upload.delete_original', 'original_delete', false, 'bool'); + $delete_original = ( + ($this->_site && $this->_config->get('jg_delete_original_user') == 1) + || ($this->_site && $this->_config->get('jg_delete_original_user') == 2 && $delete_original) + || (!$this->_site && $this->_config->get('jg_delete_original') == 1) + || (!$this->_site && $this->_config->get('jg_delete_original') == 2 && $delete_original) + ); + if( ($delete_original && !$is_in_original && $delete_source) + || ($delete_original && $is_in_original) + ) + { + if($detail_image_created) + { + // Remove image from originals if chosen in backend + if(JFile::delete($source)) + { + $this->_debugoutput .= JText::_('COM_JOOMGALLERY_UPLOAD_OUTPUT_ORIGINAL_DELETED').'
    '; + } + else + { + $this->_debugoutput .= JText::sprintf('COM_JOOMGALLERY_UPLOAD_OUTPUT_PROBLEM_DELETING_ORIGINAL', $this->_ambit->getImg('orig_path', $filename, null, $this->catid)).' '.JText::_('COM_JOOMGALLERY_COMMON_CHECK_PERMISSIONS').'
    '; + $this->debug = true; + return false; + } + } + else + { + // Move original image to detail images folder if original image shall be deleted and detail image wasn't resized + $return = JFile::move($source, + $this->_ambit->getImg('img_path', $filename, null, $this->catid)); + if(!$return) + { + $this->_debugoutput .= JText::sprintf('COM_JOOMGALLERY_UPLOAD_OUTPUT_PROBLEM_MOVING', $this->_ambit->getImg('img_path', $filename, null, $this->catid)).'
    '; + $this->debug = true; + return false; + } + } + } + else + { + if(!$detail_image_created) + { + // Copy original image into detail images folder if original image shouldn't be deleted and detail image wasn't resized + $return = JFile::copy($source, + $this->_ambit->getImg('img_path', $filename, null, $this->catid)); + if(!$return) + { + $this->_debugoutput .= JText::sprintf('COM_JOOMGALLERY_UPLOAD_OUTPUT_PROBLEM_COPYING', $this->_ambit->getImg('img_path', $filename, null, $this->catid)).'
    '; + $this->debug = true; + return false; + } + + if($delete_original && !$is_in_original && !$delete_source) + { + if(JFile::delete($source)) + { + $this->_debugoutput .= JText::_('COM_JOOMGALLERY_UPLOAD_OUTPUT_ORIGINAL_DELETED').'
    '; + } + else + { + $this->_debugoutput .= JText::sprintf('COM_JOOMGALLERY_UPLOAD_OUTPUT_PROBLEM_DELETING_ORIGINAL', $this->_ambit->getImg('orig_path', $filename, null, $this->catid)).' '.JText::_('COM_JOOMGALLERY_COMMON_CHECK_PERMISSIONS').'
    '; + $this->debug = true; + return false; + } + } + } + } + + // Set permissions of detail image + if($detail_image_created) + { + $return = JoomFile::chmod($this->_ambit->getImg('img_path', $filename, null, $this->catid), '0644'); + /*if(!$return) + { + $this->_debugoutput .= $this->_ambit->getImg('img_path', $filename, null, $this->catid).' '.JText::_('COM_JOOMGALLERY_COMMON_CHECK_PERMISSIONS').'
    '; + $this->debug = true; + return false; + }*/ + } + + if(!$delete_original && !$is_in_original && !$delete_source) + { + // Copy source file to orginal images folder if original image shouldn't be deleted and if it's not already there + $return = JFile::copy($source, + $this->_ambit->getImg('orig_path', $filename, null, $this->catid)); + if(!$return) + { + $this->_debugoutput .= JText::sprintf('COM_JOOMGALLERY_UPLOAD_OUTPUT_PROBLEM_COPYING', $this->_ambit->getImg('orig_path', $filename, null, $this->catid)).'
    '; + $this->debug = true; + return false; + } + } + else + { + if(!$delete_original && !$is_in_original && $delete_source) + { + // Move source file to orginal images folder if original image shall be deleted and if it's not already there + $return = JFile::move($source, + $this->_ambit->getImg('orig_path', $filename, null, $this->catid)); + if(!$return) + { + $this->_debugoutput .= JText::sprintf('COM_JOOMGALLERY_UPLOAD_OUTPUT_PROBLEM_MOVING', $this->_ambit->getImg('orig_path', $filename, null, $this->catid)).'
    '; + $this->debug = true; + return false; + } + } + } + + return true; + } + + /** + * Creates the database entry for a successfully uploaded image + * + * @param object $row The JTable object of the images table to work with + * @param string $origfilename The original file name of the uploaded image + * @param string $newfilename The new file name for the image + * @param string $tag The extension of the uploaded image + * @param int $serial The counter for the numbering of the image titles + * @return boolean True on success, false otherwise + * @since 1.5.7 + */ + protected function registerImage($row, $origfilename, $newfilename, $tag, $serial = null) + { + // Get the specified image information (either from session or from post) + $old_info = $this->_mainframe->getUserState('joom.upload.post'); + $cur_info = (!is_null($old_info)) ? $old_info : array(); + $new_info = JRequest::get('post'); + + // Prevent setting access level in frontend + if(isset($new_info['access']) && $this->_site) + { + unset($new_info['access']); + } + + // Save the new value only if it was set in this request + if(count($new_info)) + { + $this->_mainframe->setUserState('joom.upload.post', $new_info); + $data = $new_info; + } + else + { + $data = $cur_info; + } + + if(!$row->bind($data)) + { + $this->_debugoutput .= $row->getError(); + $this->debug = true; + return false; + } + + // Image title + if( ($this->_site && $this->_config->get('jg_useruseorigfilename')) + || + (!$this->_site && $this->_config->get('jg_useorigfilename')) + ) + { + $taglength = strlen($tag); + $filenamelength = strlen($origfilename); + $row->imgtitle = substr($origfilename, -$filenamelength, -$taglength - 1); + } + + // Add counter number if set in backend + if(!is_null($serial)) + { + $imgname_separator = JText::_('COM_JOOMGALLERY_UPLOAD_IMAGENAME_SEPARATOR'); + if($imgname_separator == 'space') + { + $imgname_separator = ' '; + } + + $row->imgtitle = $row->imgtitle.$imgname_separator.$serial; + } + + // Owner + if($this->_site) + { + $row->owner = $this->_user->get('id'); + } + else + { + $row->owner = 0; + } + + // Date + $date = JFactory::getDate(); + $row->imgdate = $date->toSQL(); + + // Check whether images are approved directly if we are in frontend + if($this->_site && $this->_config->get('jg_approve') == 1) + { + $row->approved = 0; + } + else + { + $row->approved = 1; + } + + $row->imgfilename = $newfilename; + $row->imgthumbname = $newfilename; + $row->useruploaded = intval($this->_site); + $row->ordering = $this->_getOrdering($row); + + if(!$row->check()) + { + $this->_debugoutput .= $row->getError().'
    '; + $this->debug = true; + return false; + } + + if(!$row->store()) + { + $this->_debugoutput .= $row->getError().'
    '; + $this->debug = true; + return false; + } + + return true; + } + + /** + * Analyses an error code and returns its text + * + * @param int $uploaderror The errorcode + * @return string The error message + * @since 1.0.0 + */ + protected function checkError($uploaderror) + { + // Common PHP errors + $uploadErrors = array( + 1 => JText::_('COM_JOOMGALLERY_UPLOAD_ERROR_PHP_MAXFILESIZE'), + 2 => JText::_('COM_JOOMGALLERY_UPLOAD_ERROR_HTML_MAXFILESIZE'), + 3 => JText::_('COM_JOOMGALLERY_UPLOAD_ERROR_FILE_PARTLY_UPLOADED'), + 4 => JText::_('COM_JOOMGALLERY_UPLOAD_ERROR_FILE_NOT_UPLOADED') + ); + + if(in_array($uploaderror, $uploadErrors)) + { + return JText::sprintf('COM_JOOMGALLERY_UPLOAD_ERROR_CODE', $uploadErrors[$uploaderror]); + } + else + { + return JText::sprintf('COM_JOOMGALLERY_UPLOAD_ERROR_CODE', JText::_('COM_JOOMGALLERY_UPLOAD_ERROR_UNKNOWN')); + } + } + + /** + * Method to check whether a category exists and to get the owner it + * + * @param int The category ID + * @return object The owner of the category and a flag (existent) if it exists + * @since 2.0 + */ + protected function getCategory($catid) + { + $query = $this->_db->getQuery(true) + ->select('cid, owner') + ->from(_JOOM_TABLE_CATEGORIES) + ->where('cid = '.$catid); + $this->_db->setQuery($query); + return $this->_db->loadObject(); + } +} diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/includes/defines.php b/deployed/joomgallery/administrator/components/com_joomgallery/includes/defines.php new file mode 100644 index 00000000..e943408d --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/includes/defines.php @@ -0,0 +1,28 @@ + array + ( + 270 => array( 'Attribute' => "ImageDescription", + 'Name' => JText::_('COM_JOOMGALLERY_IFD0_IMAGEDESCRIPTION'), + 'Description' => JText::_('COM_JOOMGALLERY_IFD0_IMAGEDESCRIPTION_DESCRIPTION'), + 'Calculation' => "", + 'Format' => "ASCII String", + 'Units' => "" + ), + 271 => array( 'Attribute' => "Make", + 'Name' => JText::_('COM_JOOMGALLERY_IFD0_MAKE'), + 'Description' => JText::_('COM_JOOMGALLERY_IFD0_MAKE_DESCRIPTION'), + 'Calculation' => "", + 'Format' => "ASCII String", + 'Units' => "" + ), + 272 => array( 'Attribute' => "Model", + 'Name' => JText::_('COM_JOOMGALLERY_IFD0_MODEL'), + 'Description' => JText::_('COM_JOOMGALLERY_IFD0_MODEL_DESCRIPTION'), + 'Calculation' => "", + 'Format' => "ASCII String", + 'Units' => "" + ), + 274 => array( 'Attribute' => "Orientation", + 'Name' => JText::_('COM_JOOMGALLERY_IFD0_ORIENTATION'), + 'Description' => JText::_('COM_JOOMGALLERY_IFD0_ORIENTATION_DESCRIPTION'), + 'Calculation' => "Array", + 'Format' => "Unsigned Short", + 'Units' => "", + 1 => JText::_('COM_JOOMGALLERY_IFD0_ORIENTATION_1'), + 2 => JText::_('COM_JOOMGALLERY_IFD0_ORIENTATION_2'), + 3 => JText::_('COM_JOOMGALLERY_IFD0_ORIENTATION_3'), + 4 => JText::_('COM_JOOMGALLERY_IFD0_ORIENTATION_4'), + 5 => JText::_('COM_JOOMGALLERY_IFD0_ORIENTATION_5'), + 6 => JText::_('COM_JOOMGALLERY_IFD0_ORIENTATION_6'), + 7 => JText::_('COM_JOOMGALLERY_IFD0_ORIENTATION_7'), + 8 => JText::_('COM_JOOMGALLERY_IFD0_ORIENTATION_8') + ), + 282 => array( 'Attribute' => "XResolution", + 'Name' => JText::_('COM_JOOMGALLERY_IFD0_XRESOLUTION'), + 'Description' => JText::_('COM_JOOMGALLERY_IFD0_XRESOLUTION_DESCRIPTION'), + 'Calculation' => "Denum", + 'Format' => "Unsigned Rational", + 'Units' => JText::_('COM_JOOMGALLERY_IFD0_DOTSPERRESOLUTIONUNIT') + ), + 283 => array( 'Attribute' => "YResolution", + 'Name' => JText::_('COM_JOOMGALLERY_IFD0_YRESOLUTION'), + 'Description' => JText::_('COM_JOOMGALLERY_IFD0_YRESOLUTION_DESCRIPTION'), + 'Calculation' => "Denum", + 'Format' => "Unsigned Rational", + 'Units' => JText::_('COM_JOOMGALLERY_IFD0_DOTSPERRESOLUTIONUNIT') + ), + 296 => array( 'Attribute' => "ResolutionUnit", + 'Name' => JText::_('COM_JOOMGALLERY_IFD0_RESOLUTIONUNIT'), + 'Description' => JText::_('COM_JOOMGALLERY_IFD0_RESOLUTIONUNIT_DESCRIPTION'), + 'Calculation' => "Array", + 'Format' => "Unsigned Short", + 'Units' => "", + 1 => JText::_('COM_JOOMGALLERY_IFD0_RESOLUTIONUNIT_1'), + 2 => JText::_('COM_JOOMGALLERY_IFD0_RESOLUTIONUNIT_2'), + 3 => JText::_('COM_JOOMGALLERY_IFD0_RESOLUTIONUNIT_3'), + 4 => JText::_('COM_JOOMGALLERY_IFD0_RESOLUTIONUNIT_4'), + 5 => JText::_('COM_JOOMGALLERY_IFD0_RESOLUTIONUNIT_5') + ), + 305 => array( 'Attribute' => "Software", + 'Name' => JText::_('COM_JOOMGALLERY_IFD0_SOFTWARE'), + 'Description' => JText::_('COM_JOOMGALLERY_IFD0_SOFTWARE_DESCRIPTION'), + 'Calculation' => "", + 'Format' => "ASCII String", + 'Units' => "" + ), + 306 => array( 'Attribute' => "DateTime", + 'Name' => JText::_('COM_JOOMGALLERY_IFD0_DATETIME'), + 'Description' => JText::_('COM_JOOMGALLERY_IFD0_DATETIME_DESCRIPTION'), + 'Calculation' => "", + 'Format' => "ASCII String", + 'Units' => "" + ), + 318 => array( 'Attribute' => "WhitePoint", + 'Name' => JText::_('COM_JOOMGALLERY_IFD0_WHITEPOINT'), + 'Description' => JText::_('COM_JOOMGALLERY_IFD0_WHITEPOINT_DESCRIPTION'), + 'Calculation' => "", + 'Format' => "Unsigned Rational", + 'Units' => "" + ), + 319 => array( 'Attribute' => "PrimaryChromaticities", + 'Name' => JText::_('COM_JOOMGALLERY_IFD0_PRIMARYCHROMATICITIES'), + 'Description' => JText::_('COM_JOOMGALLERY_IFD0_PRIMARYCHROMATICITIES_DESCRIPTION'), + 'Calculation' => "", + 'Format' => "Unsigned Rational", + 'Units' => "" + ), + 529 => array( 'Attribute' => "YCbCrCoefficients", + 'Name' => JText::_('COM_JOOMGALLERY_IFD0_YCBCRCOEFFICIENTS'), + 'Description' => JText::_('COM_JOOMGALLERY_IFD0_YCBCRCOEFFICIENTS_DESCRIPTION'), + 'Calculation' => "", + 'Format' => "Unsigned Rational", + 'Units' => "" + ), + 531 => array( 'Attribute' => "YCbCrPositioning", + 'Name' => JText::_('COM_JOOMGALLERY_IFD0_YCBCRPOSITIONING'), + 'Description' => JText::_('COM_JOOMGALLERY_IFD0_YCBCRPOSITIONING_DESCRIPTION'), + 'Calculation' => "Array", + 'Format' => "Unsigned Short", + 'Units' => "", + 1 => JText::_('COM_JOOMGALLERY_IFD0_YCBCRPOSITIONING_1'), + 2 => JText::_('COM_JOOMGALLERY_IFD0_YCBCRPOSITIONING_2') + ), + 532 => array( 'Attribute' => "ReferenceBlackWhite", + 'Name' => JText::_('COM_JOOMGALLERY_IFD0_REFERENCEBLACKWHITE'), + 'Description' => JText::_('COM_JOOMGALLERY_IFD0_REFERENCEBLACKWHITE_DESCRIPTION'), + 'Calculation' => "", + 'Format' => "Unsigned Rational", + 'Units' => "" + ), + 315 => array( 'Attribute' => "Artist", + 'Name' => JText::_('COM_JOOMGALLERY_IFD0_ARTIST'), + 'Description' => JText::_('COM_JOOMGALLERY_IFD0_ARTIST_DESCRIPTION'), + 'Calculation' => "", + 'Format' => "ASCII String", + 'Units' => "" + ), + 33432 => array( 'Attribute' => "Copyright", + 'Name' => JText::_('COM_JOOMGALLERY_IFD0_COPYRIGHT'), + 'Description' => JText::_('COM_JOOMGALLERY_IFD0_COPYRIGHT_DESCRIPTION'), + 'Calculation' => "", + 'Format' => "ASCII String", + 'Units' => "" + ), + ), + + 'EXIF' => array + ( + 33434 => array( 'Attribute' => "ExposureTime", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_EXPOSURETIME'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_EXPOSURETIME_DESCRIPTION'), + 'Calculation' => "", + 'Format' => "Unsigned Rational", + 'Units' => JText::_('COM_JOOMGALLERY_SECONDS') + ), + 33437 => array( 'Attribute' => "FNumber", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_FNUMBER'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_FNUMBER_DESCRIPTION'), + 'Calculation' => "Denum", + 'Format' => "Unsigned Rational", + 'Units' => "" + ), + 34850 => array( 'Attribute' => "ExposureProgram", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_EXPOSUREPROGRAM'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_EXPOSUREPROGRAM_DESCRIPTION'), + 'Calculation' => "Array", + 'Format' => "Unsigned Short", + 'Units' => "", + 0 => JText::_('COM_JOOMGALLERY_SUBIFD_EXPOSUREPROGRAM_0'), + 1 => JText::_('COM_JOOMGALLERY_SUBIFD_EXPOSUREPROGRAM_1'), + 2 => JText::_('COM_JOOMGALLERY_SUBIFD_EXPOSUREPROGRAM_2'), + 3 => JText::_('COM_JOOMGALLERY_SUBIFD_EXPOSUREPROGRAM_3'), + 4 => JText::_('COM_JOOMGALLERY_SUBIFD_EXPOSUREPROGRAM_4'), + 5 => JText::_('COM_JOOMGALLERY_SUBIFD_EXPOSUREPROGRAM_5'), + 6 => JText::_('COM_JOOMGALLERY_SUBIFD_EXPOSUREPROGRAM_6'), + 7 => JText::_('COM_JOOMGALLERY_SUBIFD_EXPOSUREPROGRAM_7'), + 8 => JText::_('COM_JOOMGALLERY_SUBIFD_EXPOSUREPROGRAM_8') + ), + 34855 => array( 'Attribute' => "ISOSpeedRatings", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_ISOSPEEDRATINGS'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_ISOSPEEDRATINGS_DESCRIPTION'), + 'Calculation' => "", + 'Format' => "Unsigned Short", + 'Units' => "" + ), + 36864 => array( 'Attribute' => "ExifVersion", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_EXIFVERSION'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_EXIFVERSION_DESCRIPTION'), + 'Calculation' => "", + 'Format' => "Undefined", + 'Units' => "" + ), + 36867 => array( 'Attribute' => "DateTimeOriginal", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_DATETIMEORIGINAL'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_DATETIMEORIGINAL_DESCRIPTION'), + 'Calculation' => "", + 'Format' => "ASCII String", + 'Units' => "" + ), + 36868 => array( 'Attribute' => "DateTimeDigitized", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_DATETIMEDIGITIZED'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_DATETIMEDIGITIZED_DESCRIPTION'), + 'Calculation' => "", + 'Format' => "ASCII String", + 'Units' => "" + ), + 37121 => array( 'Attribute' => "ComponentsConfiguration", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_COMPONENTSCONFIGURATION'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_COMPONENTSCONFIGURATION_DESCRIPTION'), + 'Calculation' => "", + 'Format' => "Undefined", + 'Units' => "" + ), + 37122 => array( 'Attribute' => "CompressedBitsPerPixel", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_COMPRESSEDBITSPERPIXEL'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_COMPRESSEDBITSPERPIXEL_DESCRIPTION'), + 'Calculation' => "Denum", + 'Format' => "Unsigned Rational", + 'Units' => JText::_('COM_JOOMGALLERY_SUBIFD_COMPRESSEDBITSPERPIXEL_UNIT') + ), + 37377 => array( 'Attribute' => "ShutterSpeedValue", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_SHUTTERSPEEDVALUE'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_SHUTTERSPEEDVALUE_DESCRIPTION'), + 'Calculation' => "Denum", + 'Format' => "Signed Rational", + 'Units' => JText::_('COM_JOOMGALLERY_SUBIFD_SHUTTERSPEEDVALUE_UNIT') + ), + 37378 => array( 'Attribute' => "ApertureValue", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_APERTUREVALUE'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_APERTUREVALUE_DESCRIPTION'), + 'Calculation' => "Denum", + 'Format' => "Unsigned Rational", + 'Units' => JText::_('COM_JOOMGALLERY_SUBIFD_APERTUREVALUE_UNIT') + ), + 37379 => array( 'Attribute' => "BrightnessValue", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_BRIGHTNESSVALUE'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_BRIGHTNESSVALUE_DESCRIPTION'), + 'Calculation' => "Denum", + 'Format' => "Signed Rational", + 'Units' => JText::_('COM_JOOMGALLERY_SUBIFD_BRIGHTNESSVALUE_UNIT') + ), + 37380 => array( 'Attribute' => "ExposureBiasValue", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_EXPOSUREBIASVALUE'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_EXPOSUREBIASVALUE_DESCRIPTION'), + 'Calculation' => "", + 'Format' => "Signed Rational", + 'Units' => JText::_('COM_JOOMGALLERY_SUBIFD_EXPOSUREBIASVALUE_UNIT') + ), + 37381 => array( 'Attribute' => "MaxApertureValue", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_MAXAPERTUREVALUE'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_MAXAPERTUREVALUE_DESCRIPTION'), + 'Calculation' => "Denum", + 'Format' => "Unsigned Rational", + 'Units' => JText::_('COM_JOOMGALLERY_SUBIFD_APERTUREVALUE_UNIT') + ), + 37382 => array( 'Attribute' => "SubjectDistance", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_SUBJECTDISTANCE'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_SUBJECTDISTANCE_DESCRIPTION'), + 'Calculation' => "", + 'Format' => "Signed Rational", + 'Units' => JText::_('COM_JOOMGALLERY_SUBIFD_SUBJECTDISTANCE_UNIT') + ), + 37383 => array( 'Attribute' => "MeteringMode", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_METERINGMODE'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_METERINGMODE_DESCRIPTION'), + 'Calculation' => "Array", + 'Format' => "Unsigned Short", + 'Units' => "", + 0 => JText::_('COM_JOOMGALLERY_SUBIFD_METERINGMODE_0'), + 1 => JText::_('COM_JOOMGALLERY_SUBIFD_METERINGMODE_1'), + 2 => JText::_('COM_JOOMGALLERY_SUBIFD_METERINGMODE_2'), + 3 => JText::_('COM_JOOMGALLERY_SUBIFD_METERINGMODE_3'), + 4 => JText::_('COM_JOOMGALLERY_SUBIFD_METERINGMODE_4'), + 5 => JText::_('COM_JOOMGALLERY_SUBIFD_METERINGMODE_5'), + 6 => JText::_('COM_JOOMGALLERY_SUBIFD_METERINGMODE_6'), + 255 => JText::_('COM_JOOMGALLERY_SUBIFD_METERINGMODE_255') + ), + 37384 => array( 'Attribute' => "LightSource", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_LIGHTSOURCE'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_LIGHTSOURCE_DESCRIPTION'), + 'Calculation' => "Array", + 'Format' => "Unsigned Short", + 'Units' => "", + 0 => JText::_('COM_JOOMGALLERY_SUBIFD_LIGHTSOURCE_0'), + 1 => JText::_('COM_JOOMGALLERY_SUBIFD_LIGHTSOURCE_1'), + 2 => JText::_('COM_JOOMGALLERY_SUBIFD_LIGHTSOURCE_2'), + 3 => JText::_('COM_JOOMGALLERY_SUBIFD_LIGHTSOURCE_3'), + 4 => JText::_('COM_JOOMGALLERY_SUBIFD_LIGHTSOURCE_4'), + 9 => JText::_('COM_JOOMGALLERY_SUBIFD_LIGHTSOURCE_9'), + 10 => JText::_('COM_JOOMGALLERY_SUBIFD_LIGHTSOURCE_10'), + 11 => JText::_('COM_JOOMGALLERY_SUBIFD_LIGHTSOURCE_11'), + 12 => JText::_('COM_JOOMGALLERY_SUBIFD_LIGHTSOURCE_12'), + 13 => JText::_('COM_JOOMGALLERY_SUBIFD_LIGHTSOURCE_13'), + 14 => JText::_('COM_JOOMGALLERY_SUBIFD_LIGHTSOURCE_14'), + 15 => JText::_('COM_JOOMGALLERY_SUBIFD_LIGHTSOURCE_15'), + 17 => JText::_('COM_JOOMGALLERY_SUBIFD_LIGHTSOURCE_17'), + 18 => JText::_('COM_JOOMGALLERY_SUBIFD_LIGHTSOURCE_18'), + 19 => JText::_('COM_JOOMGALLERY_SUBIFD_LIGHTSOURCE_19'), + 20 => JText::_('COM_JOOMGALLERY_SUBIFD_LIGHTSOURCE_20'), + 21 => JText::_('COM_JOOMGALLERY_SUBIFD_LIGHTSOURCE_21'), + 22 => JText::_('COM_JOOMGALLERY_SUBIFD_LIGHTSOURCE_22'), + 23 => JText::_('COM_JOOMGALLERY_SUBIFD_LIGHTSOURCE_23'), + 24 => JText::_('COM_JOOMGALLERY_SUBIFD_LIGHTSOURCE_24'), + 255 => JText::_('COM_JOOMGALLERY_SUBIFD_LIGHTSOURCE_255') + ), + 37385 => array( 'Attribute' => "Flash", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_FLASH'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_FLASH_DESCRIPTION'), + 'Calculation' => "Array", + 'Format' => "Unsigned Short", + 'Units' => "", + 0 => JText::_('COM_JOOMGALLERY_SUBIFD_FLASH_0'), + 1 => JText::_('COM_JOOMGALLERY_SUBIFD_FLASH_1'), + 5 => JText::_('COM_JOOMGALLERY_SUBIFD_FLASH_5'), + 7 => JText::_('COM_JOOMGALLERY_SUBIFD_FLASH_7'), + 8 => JText::_('COM_JOOMGALLERY_SUBIFD_FLASH_8'), + 9 => JText::_('COM_JOOMGALLERY_SUBIFD_FLASH_9'), + 13 => JText::_('COM_JOOMGALLERY_SUBIFD_FLASH_13'), + 15 => JText::_('COM_JOOMGALLERY_SUBIFD_FLASH_15'), + 16 => JText::_('COM_JOOMGALLERY_SUBIFD_FLASH_16'), + 20 => JText::_('COM_JOOMGALLERY_SUBIFD_FLASH_20'), + 24 => JText::_('COM_JOOMGALLERY_SUBIFD_FLASH_24'), + 25 => JText::_('COM_JOOMGALLERY_SUBIFD_FLASH_25'), + 29 => JText::_('COM_JOOMGALLERY_SUBIFD_FLASH_29'), + 31 => JText::_('COM_JOOMGALLERY_SUBIFD_FLASH_31'), + 32 => JText::_('COM_JOOMGALLERY_SUBIFD_FLASH_32'), + 48 => JText::_('COM_JOOMGALLERY_SUBIFD_FLASH_48'), + 65 => JText::_('COM_JOOMGALLERY_SUBIFD_FLASH_65'), + 69 => JText::_('COM_JOOMGALLERY_SUBIFD_FLASH_69'), + 71 => JText::_('COM_JOOMGALLERY_SUBIFD_FLASH_71'), + 73 => JText::_('COM_JOOMGALLERY_SUBIFD_FLASH_73'), + 77 => JText::_('COM_JOOMGALLERY_SUBIFD_FLASH_77'), + 79 => JText::_('COM_JOOMGALLERY_SUBIFD_FLASH_79'), + 80 => JText::_('COM_JOOMGALLERY_SUBIFD_FLASH_80'), + 88 => JText::_('COM_JOOMGALLERY_SUBIFD_FLASH_88'), + 89 => JText::_('COM_JOOMGALLERY_SUBIFD_FLASH_89'), + 93 => JText::_('COM_JOOMGALLERY_SUBIFD_FLASH_93'), + 95 => JText::_('COM_JOOMGALLERY_SUBIFD_FLASH_95') + ), + 37386 => array( 'Attribute' => "FocalLength", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_FOCALLENGTH'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_FOCALLENGTH_DESCRIPTION'), + 'Calculation' => "Denum", + 'Format' => "Unsigned Rational", + 'Units' => JText::_('COM_JOOMGALLERY_SUBIFD_FOCALLENGTH_UNIT') + ), +// 37510 => array( 'Attribute' => "UserComment", +// 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_USERCOMMENT'), +// 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_USERCOMMENT_DESCRIPTION'), +// 'Calculation' => "", +// 'Format' => "Undefined", +// 'Units' => "" +// ), +// 37520 => array( 'Attribute' => "SubsecTime", +// 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_SUBSECTIME'), +// 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_SUBSECTIME_DESCRIPTION'), +// 'Calculation' => "", +// 'Format' => "ASCII String", +// 'Units' => "" +// ), +// 37521 => array( 'Attribute' => "SubsecTimeOriginal", +// 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_SUBSECTIMEORIGINAL'), +// 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_SUBSECTIMEORIGINAL_DESCRIPTION'), +// 'Calculation' => "", +// 'Format' => "ASCII String", +// 'Units' => "" +// ), +// 37522 => array( 'Attribute' => "SubsecTimeDigitized", +// 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_SUBSECTIMEDIGITIZED'), +// 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_SUBSECTIMEDIGITIZED_DESCRIPTION'), +// 'Calculation' => "", +// 'Format' => "ASCII String", +// 'Units' => "" +// ), +// 40960 => array( 'Attribute' => "FlashPixVersion", +// 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_FLASHPIXVERSION'), +// 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_FLASHPIXVERSION_DESCRIPTION'), +// 'Calculation' => "", +// 'Format' => "Undefined", +// 'Units' => "" +// ), + 40961 => array( 'Attribute' => "ColorSpace", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_COLORSPACE'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_COLORSPACE_DESCRIPTION'), + 'Calculation' => "Array", + 'Format' => "Unsigned Short", + 'Units' => "", + 1 => JText::_('COM_JOOMGALLERY_SUBIFD_COLORSPACE_SRGB'), + 65535 => JText::_('COM_JOOMGALLERY_SUBIFD_COLORSPACE_65535') + ), + 40962 => array( 'Attribute' => "ExifImageWidth", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_EXIFIMAGEWIDTH'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_EXIFIMAGEWIDTH_DESCRIPTION'), + 'Calculation' => "", + 'Format' => "Unsigned Short/Long", + 'Units' => JText::_('COM_JOOMGALLERY_SUBIFD_EXIFIMAGEWIDTHLENGTH_UNIT') + ), + 40963 => array( 'Attribute' => "ExifImageLength", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_EXIFIMAGELENGTH'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_EXIFIMAGELENGTH_DESCRIPTION'), + 'Calculation' => "", + 'Format' => "Unsigned Short/Long", + 'Units' => JText::_('COM_JOOMGALLERY_SUBIFD_EXIFIMAGEWIDTHLENGTH_UNIT') + ), +// 40964 => array( 'Attribute' => "RelatedSoundFile", +// 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_RELATEDSOUNDFILE'), +// 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_RELATEDSOUNDFILE_DESCRIPTION'), +// 'Calculation' => "", +// 'Format' => "ASCII String", +// 'Units' => "" +// ), +// 40965 => array( 'Attribute' => "ExifInteroperabilityOffset", +// 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_EXIFINTEROPERABILITYOFFSET'), +// 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_EXIFINTEROPERABILITYOFFSET_DESCRIPTION'), +// 'Calculation' => "", +// 'Format' => "Unsigned Long", +// 'Units' => "" +// ), + 41486 => array( 'Attribute' => "FocalPlaneXResolution", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_FOCALPLANEXRESOLUTION'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_FOCALPLANEXRESOLUTION_DESCRIPTION'), + 'Calculation' => "Denum", + 'Format' => "Unsigned Rational", + 'Units' => JText::_('COM_JOOMGALLERY_SUBIFD_FOCALPLANEXYRESOLUTION_UNIT') + ), + 41487 => array( 'Attribute' => "FocalPlaneYResolution", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_FOCALPLANEYRESOLUTION'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_FOCALPLANEYRESOLUTION_DESCRIPTION'), + 'Calculation' => "Denum", + 'Format' => "Unsigned Rational", + 'Units' => JText::_('COM_JOOMGALLERY_SUBIFD_FOCALPLANEXYRESOLUTION_UNIT') + ), + 41488 => array( 'Attribute' => "FocalPlaneResolutionUnit", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_FOCALPLANERESOLUTIONUNIT'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_FOCALPLANERESOLUTIONUNIT_DESCRIPTION'), + 'Calculation' => "Array", + 'Format' => "Unsigned Short", + 'Units' => "", + 1 => JText::_('COM_JOOMGALLERY_SUBIFD_FOCALPLANERESOLUTIONUNIT_1'), + 2 => JText::_('COM_JOOMGALLERY_SUBIFD_FOCALPLANERESOLUTIONUNIT_2'), + 3 => JText::_('COM_JOOMGALLERY_SUBIFD_FOCALPLANERESOLUTIONUNIT_3') + ), + 41493 => array( 'Attribute' => "ExposureIndex", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_EXPOSUREINDEX'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_EXPOSUREINDEX_DESCRIPTION'), + 'Calculation' => "", + 'Format' => "Unsigned Rational", + 'Units' => "" + ), + 41495 => array( 'Attribute' => "SensingMethod", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_SENSINGMETHOD'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_SENSINGMETHOD_DESCRIPTION'), + 'Calculation' => "Array", + 'Format' => "Unsigned Short", + 'Units' => "", + 1 => JText::_('COM_JOOMGALLERY_SUBIFD_SENSINGMETHOD_1'), + 2 => JText::_('COM_JOOMGALLERY_SUBIFD_SENSINGMETHOD_2'), + 3 => JText::_('COM_JOOMGALLERY_SUBIFD_SENSINGMETHOD_3'), + 4 => JText::_('COM_JOOMGALLERY_SUBIFD_SENSINGMETHOD_4'), + 5 => JText::_('COM_JOOMGALLERY_SUBIFD_SENSINGMETHOD_5'), + 7 => JText::_('COM_JOOMGALLERY_SUBIFD_SENSINGMETHOD_7'), + 8 => JText::_('COM_JOOMGALLERY_SUBIFD_SENSINGMETHOD_8') + ), + 41728 => array( 'Attribute' => "FileSource", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_FILESOURCE'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_FILESOURCE_DESCRIPTION'), + 'Calculation' => "", + 'Format' => "Undefined", + 'Units' => "", + 3 => JText::_('COM_JOOMGALLERY_SUBIFD_FILESOURCE_3') + ), + 41729 => array( 'Attribute' => "SceneType", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_SCENETYPE'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_SCENETYPE_DESCRIPTION'), + 'Calculation' => "", + 'Format' => "Undefined", + 'Units' => "", + 1 => JText::_('COM_JOOMGALLERY_SUBIFD_SCENETYPE_1') + ), + 41986 => array( 'Attribute' => "ExposureMode", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_EXPOSUREMODE'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_EXPOSUREMODE_DESCRIPTION'), + 'Calculation' => "Array", + 'Format' => "Unsigned Short", + 'Units' => "", + 0 => JText::_('COM_JOOMGALLERY_SUBIFD_EXPOSUREMODE_0'), + 1 => JText::_('COM_JOOMGALLERY_SUBIFD_EXPOSUREMODE_1'), + 2 => JText::_('COM_JOOMGALLERY_SUBIFD_EXPOSUREMODE_2') + ), + 41987 => array( 'Attribute' => "WhiteBalance", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_WHITEBALANCE'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_WHITEBALANCE_DESCRIPTION'), + 'Calculation' => "Array", + 'Format' => "Unsigned Short", + 'Units' => "", + 0 => JText::_('COM_JOOMGALLERY_SUBIFD_WHITEBALANCE_0'), + 1 => JText::_('COM_JOOMGALLERY_SUBIFD_WHITEBALANCE_1') + ), + 41988 => array( 'Attribute' => "DigitalZoomRatio", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_DIGITALZOOMRATIO'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_DIGITALZOOMRATIO_DESCRIPTION'), + 'Calculation' => "", + 'Format' => "Unsigned Rational", + 'Units' => "" + ), + 41989 => array( 'Attribute' => "FocalLengthIn35mmFilm", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_FOCALLENGTHIN35MMFILM'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_FOCALLENGTHIN35MMFILM_DESCRIPTION'), + 'Calculation' => "", + 'Format' => "Unsigned Short", + 'Units' => JText::_('COM_JOOMGALLERY_SUBIFD_FOCALLENGTHIN35MMFILM_UNIT') + ), + 41990 => array( 'Attribute' => "SceneCaptureType", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_SCENECAPTURETYPE'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_SCENECAPTURETYPE_DESCRIPTION'), + 'Calculation' => "Array", + 'Format' => "Unsigned Short", + 'Units' => "", + 0 => JText::_('COM_JOOMGALLERY_SUBIFD_SCENECAPTURETYPE_0'), + 1 => JText::_('COM_JOOMGALLERY_SUBIFD_SCENECAPTURETYPE_1'), + 2 => JText::_('COM_JOOMGALLERY_SUBIFD_SCENECAPTURETYPE_2'), + 3 => JText::_('COM_JOOMGALLERY_SUBIFD_SCENECAPTURETYPE_3') + ), + 41991 => array( 'Attribute' => "GainControl", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_GAINCONTROL'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_GAINCONTROL_DESCRIPTION'), + 'Calculation' => "Array", + 'Format' => "Unsigned Rational", + 'Units' => "", + 0 => JText::_('COM_JOOMGALLERY_SUBIFD_GAINCONTROL_0'), + 1 => JText::_('COM_JOOMGALLERY_SUBIFD_GAINCONTROL_1'), + 2 => JText::_('COM_JOOMGALLERY_SUBIFD_GAINCONTROL_2'), + 3 => JText::_('COM_JOOMGALLERY_SUBIFD_GAINCONTROL_3'), + 4 => JText::_('COM_JOOMGALLERY_SUBIFD_GAINCONTROL_4') + ), + 41992 => array( 'Attribute' => "Contrast", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_CONTRAST'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_CONTRAST_DESCRIPTION'), + 'Calculation' => "Array", + 'Format' => "Unsigned Short", + 'Units' => "", + 0 => JText::_('COM_JOOMGALLERY_SUBIFD_CONTRAST_0'), + 1 => JText::_('COM_JOOMGALLERY_SUBIFD_CONTRAST_1'), + 2 => JText::_('COM_JOOMGALLERY_SUBIFD_CONTRAST_2') + ), + 41993 => array( 'Attribute' => "Saturation", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_SATURATION'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_SATURATION_DESCRIPTION'), + 'Calculation' => "Array", + 'Format' => "Unsigned Short", + 'Units' => "", + 0 => JText::_('COM_JOOMGALLERY_SUBIFD_SATURATION_0'), + 1 => JText::_('COM_JOOMGALLERY_SUBIFD_SATURATION_1'), + 2 => JText::_('COM_JOOMGALLERY_SUBIFD_SATURATION_2') + ), + 41994 => array( 'Attribute' => "Sharpness", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_SHARPNESS'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_SHARPNESS_DESCRIPTION'), + 'Calculation' => "Array", + 'Format' => "Unsigned Short", + 'Units' => "", + 0 => JText::_('COM_JOOMGALLERY_SUBIFD_SHARPNESS_0'), + 1 => JText::_('COM_JOOMGALLERY_SUBIFD_SHARPNESS_1'), + 2 => JText::_('COM_JOOMGALLERY_SUBIFD_SHARPNESS_2') + ), +// 41995 => array( 'Attribute' => "DeviceSettingDescription", +// 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_DEVICESETTINGDESCRIPTION'), +// 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_DEVICESETTINGDESCRIPTION_DESCRIPTION'), +// 'Calculation' => "", +// 'Format' => "Undefined", +// 'Units' => "" +// ), + 41996 => array( 'Attribute' => "SubjectDistanceRange", + 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_SUBJECTDISTANCERANGE'), + 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_SUBJECTDISTANCERANGE_DESCRIPTION'), + 'Calculation' => "Array", + 'Format' => "Unsigned Short", + 'Units' => "", + 0 => JText::_('COM_JOOMGALLERY_SUBIFD_SUBJECTDISTANCERANGE_0'), + 1 => JText::_('COM_JOOMGALLERY_SUBIFD_SUBJECTDISTANCERANGE_1'), + 2 => JText::_('COM_JOOMGALLERY_SUBIFD_SUBJECTDISTANCERANGE_2'), + 3 => JText::_('COM_JOOMGALLERY_SUBIFD_SUBJECTDISTANCERANGE_3') + ), +// 42016 => array( 'Attribute' => "ImageUniqueID", +// 'Name' => JText::_('COM_JOOMGALLERY_SUBIFD_IMAGEUNIQUEID'), +// 'Description' => JText::_('COM_JOOMGALLERY_SUBIFD_IMAGEUNIQUEID_DESCRIPTION'), +// 'Calculation' => "", +// 'Format' => "", +// 'Units' => "" +// ) + ), + + "GPS" => array + ( +// 0 => array( 'Attribute' => "GPSVersionID", +// 'Name' => JText::_('COM_JOOMGALLERY_GPS_GPSVERSIONID'), +// 'Description' => JText::_('COM_JOOMGALLERY_GPS_GPSVERSIONID_DESCRIPTION'), +// 'Calculation' => "", +// 'Format' => "Byte", +// 'Units' => "" +// ), + 1 => array( 'Attribute' => "GPSLatitudeRef", + 'Name' => JText::_('COM_JOOMGALLERY_GPS_GPSLATITUDEREF'), + 'Description' => JText::_('COM_JOOMGALLERY_GPS_GPSLATITUDEREF_DESCRIPTION'), + 'Calculation' => "", + 'Format' => "ASCII String", + 'Units' => "" + ), + 2 => array( 'Attribute' => "GPSLatitude", + 'Name' => JText::_('COM_JOOMGALLERY_GPS_GPSLATITUDE'), + 'Description' => JText::_('COM_JOOMGALLERY_GPS_GPSLATITUDE_DESCRIPTION'), + 'Calculation' => "DegMinSec", + 'Format' => "Unsigned Rational", + 'Units' => "" + ), + 3 => array( 'Attribute' => "GPSLongitudeRef", + 'Name' => JText::_('COM_JOOMGALLERY_GPS_GPSLONGITUDEREF'), + 'Description' => JText::_('COM_JOOMGALLERY_GPS_GPSLONGITUDEREF_DESCRIPTION'), + 'Calculation' => "", + 'Format' => "ASCII String", + 'Units' => "" + ), + 4 => array( 'Attribute' => "GPSLongitude", + 'Name' => JText::_('COM_JOOMGALLERY_GPS_GPSLONGITUDE'), + 'Description' => JText::_('COM_JOOMGALLERY_GPS_GPSLONGITUDE_DESCRIPTION'), + 'Calculation' => "DegMinSec", + 'Format' => "Unsigned Rational", + 'Units' => "" + ), + 5 => array( 'Attribute' => "GPSAltitudeRef", + 'Name' => JText::_('COM_JOOMGALLERY_GPS_GPSALTITUDEREF'), + 'Description' => JText::_('COM_JOOMGALLERY_GPS_GPSALTITUDEREF_DESCRIPTION'), + 'Calculation' => "", + 'Format' => "Byte", + 'Units' => "" + ), + 6 => array( 'Attribute' => "GPSAltitude", + 'Name' => JText::_('COM_JOOMGALLERY_GPS_GPSALTITUDE'), + 'Description' => JText::_('COM_JOOMGALLERY_GPS_GPSALTITUDE_DESCRIPTION'), + 'Calculation' => "Denum", + 'Format' => "Unsigned Rational", + 'Units' => JText::_('COM_JOOMGALLERY_GPS_GPSALTITUDE_UNIT') + ), + ), + ); \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/includes/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/includes/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/includes/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/includes/iptcarray.php b/deployed/joomgallery/administrator/components/com_joomgallery/includes/iptcarray.php new file mode 100644 index 00000000..87baf33f --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/includes/iptcarray.php @@ -0,0 +1,181 @@ + array + ( +// 204 => array('Attribute' => "Object Attribute Reference", +// 'Name' => JText::_('COM_JOOMGALLERY_IPTC_INTELLECTUALGENRE'), +// 'Description' => JText::_('COM_JOOMGALLERY_IPTC_INTELLECTUALGENRE_DEFINITION'), +// 'Group' => "Object", +// 'IMM' => "2:004", +// 'Format' => "Characters", +// 'Length' => "256" +// ), + 205 => array('Attribute' => "Object Name", + 'Name' => JText::_('COM_JOOMGALLERY_IPTC_TITLE'), + 'Description' => JText::_('COM_JOOMGALLERY_IPTC_TITLE_DEFINITION'), + 'Group' => "Object", + 'IMM' => "2:005", + 'Format' => "Characters", + 'Length' => "64" + ), + 225 => array('Attribute' => "Keywords", + 'Name' => JText::_('COM_JOOMGALLERY_IPTC_KEYWORDS'), + 'Description' => JText::_('COM_JOOMGALLERY_IPTC_KEYWORDS_DEFINITION'), + 'Group' => "Keywords", + 'IMM' => "2:025", + 'Format' => "Characters", + 'Length' => "each max. 64" + ), + 240 => array('Attribute' => "Special Instructions", + 'Name' => JText::_('COM_JOOMGALLERY_IPTC_INSTRUCTIONS'), + 'Description' => JText::_('COM_JOOMGALLERY_IPTC_INSTRUCTIONS_DEFINITION'), + 'Group' => "Caption", + 'IMM' => "2:040", + 'Format' => "Characters", + 'Length' => "256" + ), + 255 => array('Attribute' => "Date Created", + 'Name' => JText::_('COM_JOOMGALLERY_IPTC_DATECREATED'), + 'Description' => JText::_('COM_JOOMGALLERY_IPTC_DATECREATED_DEFINITION'), + 'Group' => "Object", + 'IMM' => "2:055", + 'Format' => "Numeric", + 'Length' => "8" + ), +// 260 => array('Attribute' => "Time Created", +// 'Name' => JText::_('COM_JOOMGALLERY_IPTC_TIMECREATED'), +// 'Description' => JText::_('COM_JOOMGALLERY_IPTC_TIMECREATED_DEFINITION'), +// 'Group' => "Object", +// 'IMM' => "2:060", +// 'Format' => "Characters", +// 'Length' => "11" +// ), + 280 => array('Attribute' => "By-line", + 'Name' => JText::_('COM_JOOMGALLERY_IPTC_CREATOR'), + 'Description' => JText::_('COM_JOOMGALLERY_IPTC_CREATOR_DEFINITION'), + 'Group' => "Contact", + 'IMM' => "2:080", + 'Format' => "Characters", + 'Length' => "32" + ), + 285 => array('Attribute' => "By-line Title", + 'Name' => JText::_('COM_JOOMGALLERY_IPTC_CREATORSJOBTITLE'), + 'Description' => JText::_('COM_JOOMGALLERY_IPTC_CREATORSJOBTITLE_DEFINITION'), + 'Group' => "Contact", + 'IMM' => "2:085", + 'Format' => "Characters", + 'Length' => "32" + ), + 290 => array('Attribute' => "City", + 'Name' => JText::_('COM_JOOMGALLERY_IPTC_CITYLEGACY'), + 'Description' => JText::_('COM_JOOMGALLERY_IPTC_CITYLEGACY_DEFINITION'), + 'Group' => "Object", + 'IMM' => "2:090", + 'Format' => "Characters", + 'Length' => "32" + ), + 292 => array('Attribute' => "Sublocation", + 'Name' => JText::_('COM_JOOMGALLERY_IPTC_SUBLOCATIONLEGACY'), + 'Description' => JText::_('COM_JOOMGALLERY_IPTC_SUBLOCATIONLEGACY_DEFINITION'), + 'Group' => "Object", + 'IMM' => "2:092", + 'Format' => "Characters", + 'Length' => "32" + ), + 295 => array('Attribute' => "Province/State", + 'Name' => JText::_('COM_JOOMGALLERY_IPTC_PROVINCEORSTATELEGACY'), + 'Description' => JText::_('COM_JOOMGALLERY_IPTC_PROVINCEORSTATELEGACY_DEFINITION'), + 'Group' => "Object", + 'IMM' => "2:095", + 'Format' => "Characters", + 'Length' => "32" + ), +// 2100 => array('Attribute' => "Country/Primary Location Code", +// 'Name' => JText::_('COM_JOOMGALLERY_IPTC_COUNTRYCODELEGACY'), +// 'Description' => JText::_('COM_JOOMGALLERY_IPTC_COUNTRYCODELEGACY_DEFINITION'), +// 'Group' => "Object", +// 'IMM' => "2:100", +// 'Format' => "Characters", +// 'Length' => "2 or 3" +// ), + 2101 => array('Attribute' => "Country/Primary Location Name", + 'Name' => JText::_('COM_JOOMGALLERY_IPTC_COUNTRYLEGACY'), + 'Description' => JText::_('COM_JOOMGALLERY_IPTC_COUNTRYLEGACY_DEFINITION'), + 'Group' => "Object", + 'IMM' => "2:101", + 'Format' => "Characters", + 'Length' => "64" + ), + 2105 => array('Attribute' => "Headline", + 'Name' => JText::_('COM_JOOMGALLERY_IPTC_HEADLINE'), + 'Description' => JText::_('COM_JOOMGALLERY_IPTC_HEADLINE_DEFINITION'), + 'Group' => "Caption", + 'IMM' => "2:105", + 'Format' => "Characters", + 'Length' => "256" + ), + 2110 => array('Attribute' => "Credit", + 'Name' => JText::_('COM_JOOMGALLERY_IPTC_CREDITLINE'), + 'Description' => JText::_('COM_JOOMGALLERY_IPTC_CREDITLINE_DEFINITION'), + 'Group' => "Credit", + 'IMM' => "2:110", + 'Format' => "Characters", + 'Length' => "32" + ), + 2115 => array('Attribute' => "Source", + 'Name' => JText::_('COM_JOOMGALLERY_IPTC_SOURCE'), + 'Description' => JText::_('COM_JOOMGALLERY_IPTC_SOURCE_DEFINITION'), + 'Group' => "Credit", + 'IMM' => "2:115", + 'Format' => "Characters", + 'Length' => "32" + ), + 2116 => array('Attribute' => "Copyright Notice", + 'Name' => JText::_('COM_JOOMGALLERY_IPTC_COPYRIGHTNOTICE'), + 'Description' => JText::_('COM_JOOMGALLERY_IPTC_COPYRIGHTNOTICE_DEFINITION'), + 'Group' => "Credit", + 'IMM' => "2:116", + 'Format' => "Characters", + 'Length' => "128" + ), + 2118 => array('Attribute' => "Contact", + 'Name' => JText::_('COM_JOOMGALLERY_IPTC_CONTACT'), + 'Description' => JText::_('COM_JOOMGALLERY_IPTC_CONTACT_DEFINITION'), + 'Group' => "Credit", + 'IMM' => "2:118", + 'Format' => "Characters", + 'Length' => "128" + ), + 2120 => array('Attribute' => "Caption/Abstract", + 'Name' => JText::_('COM_JOOMGALLERY_IPTC_DESCRIPTION'), + 'Description' => JText::_('COM_JOOMGALLERY_IPTC_DESCRIPTION_DEFINITION'), + 'Group' => "Caption", + 'IMM' => "2:120", + 'Format' => "Characters", + 'Length' => "2000" + ), + 2122 => array('Attribute' => "Writer/Editor", + 'Name' => JText::_('COM_JOOMGALLERY_IPTC_DESCRIPTIONWRITER'), + 'Description' => JText::_('COM_JOOMGALLERY_IPTC_DESCRIPTIONWRITER_DEFINITION'), + 'Group' => "Caption", + 'IMM' => "2:122", + 'Format' => "Characters", + 'Length' => "128" + ), + ), + ); \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/includes/popup.php b/deployed/joomgallery/administrator/components/com_joomgallery/includes/popup.php new file mode 100644 index 00000000..94bdc48f --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/includes/popup.php @@ -0,0 +1,152 @@ +fetchIconClass($icon); + + if ($icon == 'apply' || $icon == 'new') + { + $btnClass = 'btn btn-small btn-success modal'; + $iconWhite = ' icon-white'; + } + else + { + $btnClass = 'btn btn-small modal'; + $iconWhite = ''; + } + + // If an ID is given we will display existing content in the popup + // otherwise we will use the given URL for fetching content. + if ($id) + { + $html = "\n"; + + JHtml::_('bootstrap.modal', $id); + } + else + { + $doTask = $this->_getCommand($url); + + $html = "\n"; + + // Build the options array for the modal + $params = array(); + $params['title'] = $title; + $params['url'] = $doTask; + $params['height'] = $height; + $params['width'] = $width; + $html .= JHtml::_('bootstrap.renderModal', 'modal-' . $name, $params); + + // If an $onClose event is passed, add it to the modal JS object + if (strlen($onClose) >= 1) + { + $html .= "\n"; + } + } + + return $html; + } + + /** + * Get the button id + * + * @param string $type Button type + * @param string $name Button name + * + * @return string Button CSS Id + * + * @since 3.0 + */ + public function fetchId($type, $name) + { + return $this->_parent->getName() . '-' . "popup-$name"; + } + + /** + * Get the JavaScript command for the button + * + * @param string $url URL for popup + * + * @return string JavaScript command string + * + * @since 3.0 + */ + private function _getCommand($url) + { + if (substr($url, 0, 4) !== 'http') + { + $url = JURI::base() . $url; + } + + return $url; + } +} diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/joomgallery.php b/deployed/joomgallery/administrator/components/com_joomgallery/joomgallery.php new file mode 100644 index 00000000..b1565139 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/joomgallery.php @@ -0,0 +1,71 @@ +authorise('core.manage', _JOOM_OPTION)) +{ + return JError::raiseWarning(404, JText::_('JERROR_ALERTNOAUTHOR')); +} + +// Enable JoomGallery plugins +JPluginHelper::importPlugin('joomgallery'); + +// Require specific controller if requested +if($controller = JRequest::getCmd('controller', 'control')) +{ + $format = JRequest::getCmd('format', 'html'); + $path = JPATH_COMPONENT.'/controllers/'.$controller.(($format != 'html') ? '.'.$format : '').'.php'; + if(file_exists($path)) + { + require_once $path; + } + else + { + $controller = ''; + } +} + +// Register some classes +JLoader::register('JoomGalleryModel', JPATH_COMPONENT.'/model.php'); +JLoader::register('JoomGalleryView', JPATH_COMPONENT.'/view.php'); +JLoader::register('JoomExtensions', JPATH_COMPONENT.'/helpers/extensions.php'); +JLoader::register('JoomHelper', JPATH_COMPONENT.'/helpers/helper.php'); +JLoader::register('JoomConfig', JPATH_COMPONENT.'/helpers/config.php'); +JLoader::register('JoomAmbit', JPATH_COMPONENT.'/helpers/ambit.php'); +JLoader::register('JoomFile', JPATH_COMPONENT.'/helpers/file.php'); +JTable::addIncludePath( JPATH_COMPONENT.'/tables'); + +// Create the controller +$classname = 'JoomGalleryController'.$controller; +$controller = new $classname(); + +// Perform the request task +$controller->execute(JFactory::getApplication()->input->get('task')); + +// Redirect if set by the controller +$controller->redirect(); \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/joomgallery.xml b/deployed/joomgallery/administrator/components/com_joomgallery/joomgallery.xml new file mode 100644 index 00000000..2f3eefdc --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/joomgallery.xml @@ -0,0 +1,97 @@ + + + JoomGallery + 2018/01/21 + JoomGallery::ProjectTeam + This component is released under the GNU/GPL License + team@joomgallery.net + http://www.joomgallery.net + 3.3.4 + JoomGallery 3 is a native Joomla! 3.x gallery component + + controllers + helpers + models + views + controller.php + index.html + interface.php + joomgallery.php + model.php + router.php + view.php + + + index.html + css + images + js + java + + + en-GB/en-GB.com_joomgallery.ini + en-GB/en-GB.com_joomgallery.exif.ini + en-GB/en-GB.com_joomgallery.iptc.ini + + + + sql/install.mysql.utf8.sql + + + + + sql/uninstall.mysql.utf8.sql + + + + + sql/updates/mysql + + + script.php + + COM_JOOMGALLERY + + COM_JOOMGALLERY_CATEGORY_MANAGER + COM_JOOMGALLERY_IMAGE_MANAGER + COM_JOOMGALLERY_COMMENTS_MANAGER + COM_JOOMGALLERY_IMAGE_UPLOAD + COM_JOOMGALLERY_AJAX_UPLOAD + COM_JOOMGALLERY_BATCH_UPLOAD + COM_JOOMGALLERY_FTP_UPLOAD + COM_JOOMGALLERY_JAVA_UPLOAD + COM_JOOMGALLERY_CONFIGURATION_MANAGER + COM_JOOMGALLERY_CUSTOMIZE_CSS + COM_JOOMGALLERY_MIGRATION_MANAGER + COM_JOOMGALLERY_MAINTENANCE_MANAGER + COM_JOOMGALLERY_HELP + + + controllers + helpers + includes + layouts + models + sql + tables + temp + views + access.xml + changelog.xml + config.xml + controller.php + index.html + joomgallery.php + LICENSE.TXT + model.php + view.php + + + en-GB/en-GB.com_joomgallery.ini + en-GB/en-GB.com_joomgallery.sys.ini + + + + http://www.en.joomgallery.net/components/com_newversion/xml/extensions3.xml + + diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/layouts/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/layouts/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/layouts/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/layouts/joomgallery/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/layouts/joomgallery/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/layouts/joomgallery/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/layouts/joomgallery/migration/checkend.php b/deployed/joomgallery/administrator/components/com_joomgallery/layouts/joomgallery/migration/checkend.php new file mode 100644 index 00000000..441969b4 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/layouts/joomgallery/migration/checkend.php @@ -0,0 +1,31 @@ + + + +
    +ready): ?> +
    +
    +
    + +
    +
    +
    + +
    + + +ready): ?> + + +
    +
    + + + +
    +
    +
    + + + + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/layouts/joomgallery/migration/checksection.php b/deployed/joomgallery/administrator/components/com_joomgallery/layouts/joomgallery/migration/checksection.php new file mode 100644 index 00000000..537e0831 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/layouts/joomgallery/migration/checksection.php @@ -0,0 +1,17 @@ + + + +

    title; ?>

    + + +checks as $check): ?> + + + + + + + + + + + + + + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/layouts/joomgallery/migration/form.php b/deployed/joomgallery/administrator/components/com_joomgallery/layouts/joomgallery/migration/form.php new file mode 100644 index 00000000..a47473cd --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/layouts/joomgallery/migration/form.php @@ -0,0 +1,44 @@ + + + + + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/layouts/joomgallery/migration/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/layouts/joomgallery/migration/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/layouts/joomgallery/migration/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/model.php b/deployed/joomgallery/administrator/components/com_joomgallery/model.php new file mode 100644 index 00000000..a24feaf5 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/model.php @@ -0,0 +1,75 @@ +_ambit = JoomAmbit::getInstance(); + $this->_config = JoomConfig::getInstance(); + + $this->_mainframe = JFactory::getApplication('administrator'); + $this->_user = JFactory::getUser(); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/models/batchupload.php b/deployed/joomgallery/administrator/components/com_joomgallery/models/batchupload.php new file mode 100644 index 00000000..eefc772a --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/models/batchupload.php @@ -0,0 +1,25 @@ +filter_fields = array( + 'cid', 'c.cid', + 'name', 'c.name', + 'alias', 'c.alias', + 'parent_id', 'c.parent_id', + 'published', 'c.published', + 'access', 'c.access', 'access_level', + 'owner', 'c.owner', + 'lft', 'c.lft', + 'rgt', 'c.rgt', + 'level', 'c.level', + 'type' + ); + } + + /** + * Retrieves the data of the categories + * + * @return array Array of objects containing the categories data from the database + * @since 1.5.5 + */ + public function getCategories() + { + // Let's load the data if it doesn't already exist + if(empty($this->_categories)) + { + // Get the data of the categories which will actually be displayed + $query = $this->_buildQuery(); + $this->_db->setQuery($query, $this->getStart(), $this->getState('list.limit')); + $current_categories = $this->_db->loadObjectList('cid'); + + // Get the complete category structure (containing only + // the categories which we are allowed to display) + $categories = $this->_ambit->getCategoryStructure(); + + $levels = array(); + $ordering = array(); + $this->_categories = array(); + foreach($categories as $key => $category) + { + // Check whether the current category will be displayed + if(isset($current_categories[$key])) + { + // If yes insert it into the array which will be used later on + $this->_categories[$key] = $current_categories[$key]; + + // Create an array which will help to organize ordering later on + $ordering[$category->parent_id][] = $key; + } + } + + $this->setState('ordering.array', $ordering); + + // Check whether we aren't displaying all categories in default order + if($this->getState('list.ordering') != 'c.lft') + { + $this->_categories = $current_categories; + + foreach($this->_categories as $key => $category) + { + // Unset all categories which aren't in category structure + // because we aren't allowed to display them + if(!isset($categories[$key])) + { + unset($this->_categories[$key]); + } + } + } + } + + return $this->_categories; + } + + /** + * Function to get the active filters + * + * @return array Associative array in the format: array('filter_published' => 0) + * + * @since 3.2.3 + */ + public function getActiveFilters() + { + $activeFilters = array(); + + if (!empty($this->filter_fields)) + { + foreach ($this->filter_fields as $filter) + { + $filterName = 'filter.' . $filter; + + if (property_exists($this->state, $filterName) && (!empty($this->state->{$filterName}) || is_numeric($this->state->{$filterName}))) + { + $activeFilters[$filter] = $this->state->get($filterName); + } + } + } + + return $activeFilters; + } + + /** + * Method to get the pagination object for the list. + * This method uses 'getTotel', 'getStart' and the current + * list limit of this view. + * + * @return object A pagination object + * @since 2.0 + */ + public function getPagination() + { + return new JPagination($this->getTotal(), $this->getStart(), $this->getState('list.limit')); + } + + /** + * Method to get the total number of categories + * + * @return int The total number of categories + * @since 1.5.5 + */ + public function getTotal() + { + // Let's load the number of categories if it doesn't already exist + if(empty($this->_total)) + { + $query = $this->_buildQuery(); + $this->_total = $this->_getListCount($query); + } + + return $this->_total; + } + + /** + * Method to get the starting number of items for the data set. + * + * @return int The starting number of items available in the data set. + * @since 2.0 + */ + public function getStart() + { + $start = $this->getState('list.start'); + $limit = $this->getState('list.limit'); + $total = $this->getTotal(); + if($start > $total - $limit) + { + $start = max(0, (int)(ceil($total / $limit) - 1) * $limit); + } + + return $start; + } + + /** + * Get the filter form + * + * @param array $data data + * @param boolean $loadData load current data + * + * @return JForm/false the JForm object or false + * + * @since 3.2.3 + */ + public function getFilterForm($data = array(), $loadData = true) + { + return $this->loadForm(_JOOM_OPTION . '.filter_categories', 'filter_categories', array('control' => '', 'load_data' => $loadData)); + } + + /** + * Method to get a form object. + * + * @param string $name The name of the form. + * @param string $source The form source. Can be XML string if file flag is set to false. + * @param array $options Optional array of options for the form creation. + * @param boolean $clear Optional argument to force load a new form. + * @param string $xpath An optional xpath to search for the fields. + * + * @return mixed JForm object on success, False on error. + * + * @see JForm + * @since 3.2.3 + */ + protected function loadForm($name, $source = null, $options = array(), $clear = false, $xpath = false) + { + // Handle the optional arguments. + $options['control'] = JArrayHelper::getValue($options, 'control', false); + + // Get the form. + JForm::addFormPath(JPATH_COMPONENT . '/models/forms'); + JForm::addFieldPath(JPATH_COMPONENT . '/models/fields'); + + try + { + $form = JForm::getInstance($name, $source, $options, false, $xpath); + + $form->setFieldAttribute('owner', 'useListboxMaxUserCount', $this->_config->get('jg_use_listbox_max_user_count'), 'filter'); + + if(isset($options['load_data']) && $options['load_data']) + { + // Get the data for the form. + $data = $this->loadFormData(); + } + else + { + $data = array(); + } + + // Load the data into the form after the plugins have operated. + $form->bind($data); + } + catch(Exception $e) + { + $this->setError($e->getMessage()); + + return false; + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 3.2.3 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = JFactory::getApplication()->getUserState('joom.categories', new stdClass); + + // Pre-fill the list options + if (!property_exists($data, 'list')) + { + $data->list = array( + 'direction' => $this->state->{'list.direction'}, + 'limit' => $this->state->{'list.limit'}, + 'ordering' => $this->state->{'list.ordering'}, + 'start' => $this->state->{'list.start'} + ); + } + + return $data; + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @param string An optional ordering field. + * @param string An optional direction (asc|desc). + * @return void + * @since 2.0 + */ + protected function populateState($ordering = 'c.lft', $direction = 'ASC') + { + // Receive & set filters + $filters = $this->getUserStateFromRequest('joom.categories.filter', 'filter', + array('search' => null, 'access' => '', 'published' => '', 'type' => '', 'owner' => ''), 'array'); + + if($filters) + { + foreach($filters as $name => $value) + { + $this->setState('filter.' . $name, $value); + + if($value) + { + $this->setState('filter.inuse', 1); + } + } + } + + $limit = 0; + + // Receive & set list options + $list = $this->getUserStateFromRequest('joom.categories.list', 'list', + array('ordering' => $ordering, 'direction' => $direction, 'fullordering' => $ordering . ' ' . $direction, + 'limit' => $this->_mainframe->getCfg('list_limit'), 'start' => 0), 'array'); + + if($list) + { + foreach($list as $name => $value) + { + // Extra validations + switch($name) + { + case 'fullordering': + $orderingParts = explode(' ', $value); + + if(count($orderingParts) >= 2) + { + // Latest part will be considered the direction + $fullDirection = end($orderingParts); + + if(in_array(strtoupper($fullDirection), array('ASC', 'DESC', ''))) + { + $this->setState('list.direction', $fullDirection); + } + + unset($orderingParts[count($orderingParts) - 1]); + + // The rest will be the ordering + $fullOrdering = implode(' ', $orderingParts); + + if(in_array($fullOrdering, $this->filter_fields)) + { + $this->setState('list.ordering', $fullOrdering); + } + } + else + { + $this->setState('list.ordering', $ordering); + $this->setState('list.direction', $direction); + } + break; + case 'ordering': + if(!in_array($value, $this->filter_fields)) + { + $value = $ordering; + } + break; + + case 'direction': + if(!in_array(strtoupper($value), array('ASC', 'DESC', ''))) + { + $value = $direction; + } + break; + + case 'limit': + $limit = $value; + break; + + // Just to keep the default case + default: + $value = $value; + break; + } + + $this->setState('list.' . $name, $value); + } + + $value = $this->getUserStateFromRequest('joom.categories.limitstart', 'limitstart', 0); + $limitstart = ($limit != 0 ? (floor($value / $limit) * $limit) : 0); + + $this->setState('list.start', $limitstart); + } + } + + /** + * Returns the query for listing the categories + * + * @return object The query to be used to retrieve the categories data from the database + * @since 1.5.5 + */ + protected function _buildQuery() + { + // Create a new query object + $query = $this->_db->getQuery(true); + + // Select the required fields from the table + $query->select('c.*') + ->from(_JOOM_TABLE_CATEGORIES.' AS c'); + + // Join over the access levels + $query->select('v.title AS access_level') + ->join('LEFT', '#__viewlevels AS v ON v.id = c.access'); + + // Join over the users + $query->join('LEFT', '#__users AS u ON u.id = c.owner'); + + // ROOT category shouldn't be selected + $query->where('parent_id > 0'); + + // Filter by allowed access levels + if(!$this->_user->authorise('core.admin')) + { + $query->where('c.access IN ('.implode(',', $this->_user->getAuthorisedViewLevels()).')'); + } + + // Filter by access level + if($access = $this->getState('filter.access')) + { + $query->where('c.access = '.(int) $access); + } + + // Filter by state + $published = $this->getState('filter.published'); + if(is_numeric($published)) + { + switch($published) + { + case 1: + // Published + $query->where('published = 1'); + break; + case 0: + // Not published + $query->where('published = 0'); + break; + default: + // No filter by state + break; + } + } + + // Filter by owner + if($owner = $this->getState('filter.owner')) + { + $query->where('c.owner = '.(int) $owner); + } + + // Filter by type + $type = $this->getState('filter.type'); + switch($type) + { + case 1: + // User categories + $query->where('c.owner != 0'); + break; + case 2: + // Administrator categories + $query->where('c.owner = 0'); + break; + default: + // No filter by type + break; + } + + // Filter by search + $search = $this->getState('filter.search'); + if(!empty($search)) + { + if(stripos($search, 'id:') === 0) + { + $query->where('c.cid = '.(int) substr($search, 3)); + } + else + { + if(stripos($search, 'author:') === 0) + { + $search = $this->_db->Quote('%'.$this->_db->escape(substr($search, 7), true).'%'); + $query->where('(u.name LIKE '.$search.' OR u.username LIKE '.$search.')'); + } + else + { + $search = $this->_db->Quote('%'.$this->_db->escape($search, true).'%'); + $query->where('(c.name LIKE '.$search.' OR c.alias LIKE '.$search.' OR LOWER(c.description) LIKE '.$search.')'); + } + } + } + + // Add the order clause + $query->order($this->_db->escape($this->getState('list.ordering', 'c.lft')).' '.$this->_db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } + + /** + * Method to delete one or more categories + * + * @param array $ids IDs of categories to delete + * @return int Number of successfully deleted categories, boolean false if an error occured + * @throws RuntimeException + * @since 1.5.5 + */ + public function delete($ids) + { + if(!count($ids)) + { + throw new RuntimeException(JText::_('COM_JOOMGALLERY_COMMON_MSG_NO_CATEGORIES_SELECTED')); + } + + $delete_categories = array(); + $delete_images = array(); + + $count = 0; + $row = $this->getTable('joomgallerycategories'); + + // Loop through selected categories + foreach($ids as $cid) + { + // Check whether we are allowed to delete this category + if(!$this->_user->authorise('core.delete', _JOOM_OPTION.'.category.'.$cid)) + { + JLog::add(JText::sprintf('COM_JOOMGALLERY_CATMAN_ERROR_DELETE_NOT_PERMITTED', $cid), JLog::ERROR, 'jerror'); + + continue; + } + + $delete = true; + + // Check whether there are sub-categories + // We can't use category structure here because sub-categories may have + // already been deleted in the same request, so the structure isn't up-to-date + $query = $this->_db->getQuery(true) + ->select('c.cid') + ->from(_JOOM_TABLE_CATEGORIES.' AS c') + ->from(_JOOM_TABLE_CATEGORIES.' AS n') + ->where('c.lft BETWEEN n.lft AND n.rgt') + ->where('n.cid = '.$cid); + $this->_db->setQuery($query); + $subcategories = $this->_db->loadColumn(); + + if(count($subcategories) > 1) + { + $msg = JText::sprintf('COM_JOOMGALLERY_CATMAN_MSG_CATEGORY_NOT_EMPTY_CATEGORIES', $cid); + $this->_mainframe->enqueueMessage($msg, 'notice'); + + $delete = false; + + $delete_categories = array_unique(array_merge($delete_categories, $subcategories)); + } + + // Database query to check assigned images to category + $query = $this->_db->getQuery(true) + ->select('id') + ->from(_JOOM_TABLE_IMAGES) + ->where('catid IN ('.implode(',', $subcategories).')'); + $this->_db->setQuery($query); + $images = $this->_db->loadColumn(); + + if(count($images)) + { + $msg = JText::sprintf('COM_JOOMGALLERY_CATMAN_MSG_CATEGORY_NOT_EMPTY_IMAGES', $cid); + $this->_mainframe->enqueueMessage($msg, 'notice'); + + $delete = false; + + $delete_images = array_unique(array_merge($delete_images, $images)); + $delete_categories = array_unique(array_merge($delete_categories, array($cid))); + } + + if($delete) + { + $catpath = JoomHelper::getCatPath($cid); + if(!$this->_deleteFolders($catpath)) + { + JLog::add(JText::_('COM_JOOMGALLERY_CATMAN_MSG_ERROR_DELETING_DIRECTORIES'), JLog::WARNING, 'jerror'); + } + + $row->load($cid); + if(!$row->delete()) + { + throw new RuntimeException($row->getError()); + } + + $this->_mainframe->triggerEvent('onContentAfterDelete', array(_JOOM_OPTION.'.category', $row)); + + // Category successfully deleted + $count++; + } + } + + $this->_mainframe->setUserState('joom.categories.delete.categories', $delete_categories); + $this->_mainframe->setUserState('joom.categories.delete.images', $delete_images); + + $cat_count = count($delete_categories); + $img_count = count($delete_images); + + if($cat_count || $img_count) + { + $msg = '
    '.JText::_('COM_JOOMGALLERY_CATMAN_MSG_DELETECOMPLETELY'); + if($img_count) + { + if($img_count == 1) + { + $msg .= '
    '.JText::_('COM_JOOMGALLERY_CATMAN_MSG_DELETECOMPLETELY_IMAGES_NUMBER_1'); + } + else + { + $msg .= '
    '.JText::sprintf('COM_JOOMGALLERY_CATMAN_MSG_DELETECOMPLETELY_IMAGES_NUMBER', $img_count); + } + } + if($cat_count) + { + if($cat_count == 1) + { + $msg .= '
    '.JText::_('COM_JOOMGALLERY_CATMAN_MSG_DELETECOMPLETELY_CATEGORIES_NUMBER_1'); + } + else + { + $msg .= '
    '.JText::sprintf('COM_JOOMGALLERY_CATMAN_MSG_DELETECOMPLETELY_CATEGORIES_NUMBER', $cat_count); + } + } + $msg .= '

    '.JText::_('COM_JOOMGALLERY_CATMAN_MSG_DELETECOMPLETELY_NOTE').'

    +
    + +

    '; + $this->_mainframe->enqueueMessage($msg, 'notice'); + } + + // Reset the user state variable 'catid' for filtering in images manager + $this->_mainframe->setUserState('joom.images.catid', 0); + + return $count; + } + + /** + * Returns given category IDs in a specific ordering + * + * @param array $categories The category IDs to order + * @param string $ordering The database table column to use for ordering + * @param string $direction The direction to use for ordering + * @return array An array with the ordered category IDs + * @since 2.0 + */ + public function getOrderedCategories($categories, $ordering = 'lft', $direction = 'ASC') + { + // Sanitise variables + JArrayHelper::toInteger($categories); + if(!in_array($ordering, $this->filter_fields)) + { + $ordering = 'lft'; + } + if(!in_array(strtoupper($direction), array('ASC', 'DESC', ''))) + { + $direction = 'ASC'; + } + + $query = $this->_db->getQuery(true) + ->select('cid') + ->from(_JOOM_TABLE_CATEGORIES) + ->where('cid IN ('.implode(',', $categories).')') + ->order($ordering.' '.$direction); + $this->_db->setQuery($query); + + return $this->_db->loadColumn(); + } + + /** + * Publishes/unpublishes or approves/rejects one or more categories + * + * @param array $cid An array of category IDs to work with + * @param int $publish 1 for publishing and approving, 0 otherwise + * @param string $task 'publish' for publishing/unpublishing, anything else otherwise + * @return int The number of successfully edited categories, boolean false if an error occured + * @since 1.5.5 + */ + public function publish($cid, $publish = 1, $task = 'publish') + { + JArrayHelper::toInteger($cid); + $publish = intval($publish); + $count = count($cid); + + $row = $this->getTable('joomgallerycategories'); + + $column = 'approved'; + if($task == 'publish') + { + $column = 'published'; + } + + foreach($cid as $catid) + { + $row->load($catid); + $row->$column = $publish; + if(!$row->check()) + { + $count--; + continue; + } + + if(!$row->store()) + { + $count--; + continue; + } + + // If publishing or unpublishung wasn't successful, decrease the + // counter of successfully published or unpublished categories + if($row->$column != $publish) + { + $count--; + } + } + + return $count; + } + + /** + * Deletes folders of an existing category + * + * @param string $catpath The catpath of the category + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + protected function _deleteFolders($catpath) + { + if(!$catpath) + { + return false; + } + + $orig_path = JPath::clean($this->_ambit->get('orig_path').$catpath); + $img_path = JPath::clean($this->_ambit->get('img_path').$catpath); + $thumb_path = JPath::clean($this->_ambit->get('thumb_path').$catpath); + + // Delete the folder of the category for the original images + if(!JFolder::delete($orig_path)) + { + // If not successfull + return false; + } + else + { + // Delete the folder of the category for the detail images + if(!JFolder::delete($img_path)) + { + // If not successful + if(JFolder::create($orig_path)) + { + JoomFile::copyIndexHtml($orig_path); + } + + return false; + } + else + { + // Delete the folder of the category for the thumbnails + if(!JFolder::delete($thumb_path)) + { + // If not successful + if(JFolder::create($orig_path)) + { + JoomFile::copyIndexHtml($orig_path); + } + if(JFolder::create($img_path)) + { + JoomFile::copyIndexHtml($img_path); + } + + return false; + } + } + } + + return true; + } + + /** + * Method for retreiving categories allowed for a certain action + * + * @param string $action Optional action to check the categories against + * @param int $filter Optional category ID which will be filtered out together with its sub-categories + * @param string $searchstring Optional string for searching specific categories (name of category will be used for searching) + * @param int $limitstart Optional limit start parameter for database query + * @return array A result set with an array of categories and indicator whether there are more results left on success, Exception object otherwise + * @since 2.1 + */ + public function getAllowedCategories($action = null, $filter = null, $searchstring = '', $limitstart = 0, $current = 0) + { + JHtml::addIncludePath(JPATH_COMPONENT.'/helpers/html'); + + // Initialise variables + $results = array('results' => array()); + + $action2 = false; + if($action == 'joom.upload') + { + $action2 = 'joom.upload.inown'; + } + if($action == 'core.create') + { + $action2 = 'joom.create.inown'; + } + if($action == 'core.edit') + { + $action2 = 'core.edit.own'; + } + + $filtered = array(); + if($filter) + { + $filtered = JoomHelper::getAllSubCategories($filter, true, true, true, false); + } + + try + { + // Create the search query + $query = $this->_db->getQuery(true) + ->select('cid, name, owner') + ->from($this->_db->qn(_JOOM_TABLE_CATEGORIES)) + ->where('cid != 1') + ->order('lft'); + if($searchstring) + { + $searchstring = $this->_db->q('%'.$searchstring.'%'); + $query->where('name LIKE '.$searchstring); + } + + // Load all results + $this->_db->setQuery($query); + $result = $this->_db->loadObjectList(); + + // Check the results starting from limit start + $count = count($result); + $j = 0; + + if( !$limitstart + && ($current == 0 || !$action || ($action == 'core.create' && $this->_user->authorise($action, _JOOM_OPTION))) + ) + { + $none = new stdclass(); + $none->cid = 0; + $none->name = JText::_('COM_JOOMGALLERY_COMMON_NO_CATEGORY'); + $none->path = ''; + $none->none = true; + $results['results'][$j] = $none; + $j++; + } + + for($i = $limitstart; $i < $count; $i++) + { + if(in_array($result[$i]->cid, $filtered)) + { + continue; + } + + if( $result[$i]->cid != $current + && $action && !$this->_user->authorise($action, _JOOM_OPTION.'.category.'.$result[$i]->cid) + && ( !$action2 + || $result[$i]->owner != $this->_user->get('id') + || !$this->_user->authorise($action2, _JOOM_OPTION.'.category.'.$result[$i]->cid) + ) + ) + { + continue; + } + + // Stop as soon as we have 10 results. + // This check is done not earlier than at this point because + // we want to know whether there is at least one more result. + if($j == 10) + { + // If 'more' is set a 'More Results' link will be displayed in the view + $results['more'] = $i; + break; + } + + $results['results'][$j] = $result[$i]; + $results['results'][$j]->path = JHtml::_('joomgallery.categorypath', $result[$i]->cid, false); + $j++; + } + } + catch(JDatabaseException $e) + { + return $e; + } + + return $results; + } + + /** + * Gets the value of a user state variable and sets it in the session + * This is the same as the method in JApplication except that this also can optionally + * force you back to the first page when a filter has changed + * + * @param string $key The key of the user state variable + * @param string $request The name of the variable passed in a request + * @param string $default The default value for the variable if not found (optional) + * @param string $type Filter for the variable, for valid values see {@link JFilterInput::clean()} (optional) + * @param boolean $resetPage If true, the limitstart in request is set to zero if the state has changed + * @return The requested user state + * @since 2.0 + */ + public function getUserStateFromRequest($key, $request, $default = null, $type = 'none', $resetPage = true) + { + $app = JFactory::getApplication(); + + $old_state = $app->getUserState($key); + $cur_state = (!is_null($old_state)) ? $old_state : $default; + $new_state = JRequest::getVar($request, null, 'default', $type); + + if($cur_state != $new_state && !is_null($new_state) && !is_null($old_state) && $resetPage) + { + JRequest::setVar('limitstart', 0); + } + + // Save the new value only if it was set in this request. + if($new_state !== null) + { + $app->setUserState($key, $new_state); + } + else + { + $new_state = $cur_state; + } + + return $new_state; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/models/category.php b/deployed/joomgallery/administrator/components/com_joomgallery/models/category.php new file mode 100644 index 00000000..08e2668e --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/models/category.php @@ -0,0 +1,1314 @@ +setId((int)$array[0]); + } + + /** + * Method to set the category identifier + * + * @param int $id The Category ID + * @return void + * @since 1.5.5 + */ + public function setId($id) + { + // Set id and wipe data + $this->_id = $id; + $this->_data = null; + } + + /** + * Method to get the data of the current category + * + * @return object An object with the category data + * @since 1.5.5 + */ + public function getData() + { + if(empty($this->_data)) + { + $row = $this->getTable('joomgallerycategories'); + $row->load($this->_id); + + $this->_data = $row; + + $this->_data->thumbnail_available = false; + if($this->_data->thumbnail) + { + $query = $this->_db->getQuery(true) + ->select('id') + ->from(_JOOM_TABLE_IMAGES) + ->where('id = '.$this->_data->thumbnail) + ->where('published = 1') + ->where('approved = 1'); + $this->_db->setQuery($query); + if($this->_db->loadResult()) + { + $this->_data->thumbnail_available = true; + } + } + } + + $this->_mainframe->triggerEvent('onContentPrepareData', array(_JOOM_OPTION.'.category', $this->_data)); + + return $this->_data; + } + + /** + * Method to check whether the category can have its state edited by the current user + * + * @param array Holds the data of the category + * @return boolean True if the current user is allowed to change the state of the category, false otherwise + * @since 2.0 + */ + protected function canEditState($data) + { + // Check for existing category + if(isset($data['cid']) && $data['cid']) + { + return $this->_user->authorise('core.edit.state', _JOOM_OPTION.'.category.'.(int) $data['cid']); + } + else + { + // Maybe it is a new category, so check against the parent category + if(isset($data['parent_id']) && $data['parent_id']) + { + return $this->_user->authorise('core.edit.state', _JOOM_OPTION.'.category.'.(int) $data['parent_id']); + } + else + { + // Default to component settings if neither category nor parent category known + return $this->_user->authorise('core.edit.state', _JOOM_OPTION); + } + } + } + + /** + * Method to get the form for the category + * + * @param array Holds the data of the category (if available) + * @return mixed A JForm object on success, false on failure + * @since 2.0 + */ + public function getForm($data = array()) + { + JForm::addFormPath(JPATH_COMPONENT.'/models/forms'); + JForm::addFieldPath(JPATH_COMPONENT.'/models/fields'); + + $form = JForm::getInstance(_JOOM_OPTION.'.category', 'category'); + if(empty($form)) + { + return false; + } + + // Allow plugins to preprocess the form + $this->preprocessForm($form, $data); + + if(!$this->canEditState($data)) + { + // Disable fields for display + $form->setFieldAttribute('ordering', 'disabled', 'true'); + $form->setFieldAttribute('published', 'disabled', 'true'); + $form->setFieldAttribute('hidden', 'disabled', 'true'); + + // Unset the data of fields which we aren't allowed to change + $form->setFieldAttribute('ordering', 'filter', 'unset'); + $form->setFieldAttribute('published', 'filter', 'unset'); + $form->setFieldAttribute('hidden', 'filter', 'unset'); + } + + return $form; + } + + /** + * Method to allow plugins to preprocess the form + * + * @param JForm $form A JForm object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import (defaults to "content"). + * @return void + * @since 2.1 + */ + protected function preprocessForm(JForm $form, $data, $group = 'content') + { + // Import the appropriate plugin group + JPluginHelper::importPlugin($group); + + // Get the dispatcher + $dispatcher = JDispatcher::getInstance(); + + // Trigger the form preparation event + $results = $dispatcher->trigger('onContentPrepareForm', array($form, $data)); + + // Check for errors encountered while preparing the form + if(count($results) && in_array(false, $results, true)) + { + // Get the last error + $error = $dispatcher->getError(); + + if(!($error instanceof Exception)) + { + throw new Exception($error); + } + } + } + + /** + * Method to store a category + * + * @return int The ID of the category, boolean false if an error occured + * @since 1.5.5 + */ + public function store() + { + $row = $this->getTable('joomgallerycategories'); + + // Get all necessary data from the post + $data = JRequest::get('post', 2); + $params = isset($data['params']) ? $data['params'] : array(); + + // Creating a main category means creating + // a category in ROOT category + if($data['parent_id'] == 0) + { + $data['parent_id'] = 1; + } + + // Check for validation errors + $form = $this->getForm($data); + $data = $this->_validate($form, $data); + if($data === false) + { + return false; + } + + // Check whether it is an existing category + if($cid = intval($data['cid'])) + { + $isNew = false; + + // Load category from the database + $row->load($cid); + + // Check whether we are allowed to edit it + $asset = _JOOM_OPTION.'.category.'.$cid; + if(!$this->_user->authorise('core.edit', $asset) && (!$this->_user->authorise('core.edit.own', $asset) || !$row->owner || $row->owner != $this->_user->get('id'))) + { + $this->_mainframe->redirect(JRoute::_('index.php?option=com_joomgallery&view=gallery', false), JText::_('COM_JOOMGALLERY_COMMON_MSG_NOT_ALLOWED_TO_EDIT_CATEGORY'), 'notice'); + } + + // Read old category name + $catname_old = $row->name; + // Read old parent assignment + $parent_old = $row->parent_id; + } + else + { + $isNew = true; + + // Alter the name and the alias //for save as copy + //if(JRequest::getCmd('task') == 'save2copy') + //{ + list($title, $alias) = $this->generateNewTitle($data['parent_id'], $data['alias'], $data['name']); + $data['name'] = $title; + $data['alias'] = $alias; + //} + } + + if(isset($data['password']) && $data['password']) + { + $salt = JUserHelper::genRandomPassword(32); + $crypt = JUserHelper::getCryptedPassword($data['password'], $salt); + $data['password'] = $crypt.':'.$salt; + } + + // Bind the form fields to the category table + if(!$row->bind($data)) + { + $this->setError($row->getError()); + + return false; + } + + // Additional parameters, if set + if(count($params)) + { + // Build parameter INI string + $txt = array(); + foreach($params as $k => $v) + { + $txt[] = $k.'='.$v; + } + $row->params = implode("\n", $txt); + } + + // Bind the rules + if(isset($data['rules'])) + { + $rules = new JAccessRules($data['rules']); + $row->setRules($rules); + } + + // If it's a new category or the category will be moved + // do an access check for the selected parent category + $valid_parent = true; + $row->parent_id = intval($row->parent_id); + if($isNew || $parent_old != $row->parent_id) + { + if($row->parent_id > 1) + { + // Get data of the parent category + $query = $this->_db->getQuery(true) + ->select('cid, owner') + ->from(_JOOM_TABLE_CATEGORIES) + ->where('cid = '.$row->parent_id); + $this->_db->setQuery($query); + $parent_category = $this->_db->loadObject(); + + if( !$parent_category + || ( !$this->_user->authorise('core.create', _JOOM_OPTION.'.category.'.$row->parent_id) + && ( !$this->_user->authorise('joom.create.inown', _JOOM_OPTION.'.category.'.$row->parent_id) + || !$parent_category->owner + || $parent_category->owner != $this->_user->get('id') + ) + ) + ) + { + $valid_parent = false; + } + } + else + { + if(!$this->_user->authorise('core.create', _JOOM_OPTION)) + { + $valid_parent = false; + } + } + } + + if($isNew) + { + // Check whether the user is allowed to store the category into the specified parent category or as a main category + if(!$valid_parent) + { + $this->setError(JText::_('COM_JOOMGALLERY_CATMAN_MSG_NOT_ALLOWED_STORE_CATEGORY_IN_PARENT')); + + return false; + } + + // Determine location in category tree + if(!isset($data['ordering']) || !$data['ordering'] || $data['ordering'] == 'first-child') + { + $row->setLocation($data['parent_id'], 'first-child'); + } + else + { + if($data['ordering'] == 'last-child') + { + $row->setLocation($data['parent_id'], 'last-child'); + } + else + { + $row->setLocation($data['ordering'], 'after'); + } + } + + // Make sure the record is valid + if(!$row->check()) + { + $this->setError($row->getError()); + return false; + } + + JFilterOutput::objectHTMLSafe($row->name); + + // Check if special characters of catname can be replaced for a valid catpath + // if resulting string is invalid set an error + $catpath = JoomFile::fixFilename($row->name); + if(JoomFile::checkValidFilename($row->name, $catpath) == false) + { + $this->setError(JText::_('COM_JOOMGALLERY_CATMAN_MSG_ERROR_INVALID_FOLDERNAME')); + + return false; + } + + // Store the entry to the database in order to get the new ID + if(!$row->store()) + { + $this->setError($row->getError()); + + return false; + } + + if($row->parent_id > 1) + { + $parent_catpath = JoomHelper::getCatPath($row->parent_id); + $catpath = $parent_catpath . $catpath; + } + + // Add the category id to catpath + $catpath .= '_'.$row->cid; + + if(!$this->_createFolders($catpath)) + { + $this->setError(JText::_('COM_JOOMGALLERY_CATMAN_MSG_ERROR_CREATING_FOLDERS')); + + // Delete the just stored database entry + $row->delete(); + + return false; + } + else + { + $row->catpath = $catpath; + + // Make sure the record is valid + if(!$row->check()) + { + $this->setError($row->getError()); + return false; + } + + // Store the entry to the database + if(!$row->store()) + { + $this->setError($row->getError()); + + return false; + } + } + + $this->_mainframe->triggerEvent('onContentAfterSave', array(_JOOM_OPTION.'.category', &$row, true)); + + // New category successfully created + return $row->cid; + } + + // Move the category folder, if parent assignment or category name changed + if($parent_old != $row->parent_id || $catname_old != $row->name) + { + // Check whether the user is allowed to move the category into the specified parent category + if(!$valid_parent) + { + // If not store the category in the old parent category and leave a message. + $row->parent_id = $parent_old; + + /*if(!$row->store()) + { + JError::raiseError(100, $row->getError()); + return false; + }*/ + $this->_mainframe->enqueueMessage(JText::_('COM_JOOMGALLERY_COMMON_MSG_NOT_ALLOWED_STORE_IMAGE_IN_CATEGORY'), 'notice'); + } + else + { + if($parent_old != $row->parent_id) + { + if(isset($data['ordering']) && $data['ordering'] != $data['cid']) + { + // Determine location in category tree + if(!$data['ordering'] || $data['ordering'] == 'first-child') + { + $row->setLocation($data['parent_id'], 'first-child'); + } + else + { + if($data['ordering'] == 'last-child') + { + $row->setLocation($data['parent_id'], 'last-child'); + } + else + { + $row->setLocation($data['ordering'], 'after'); + } + } + } + else + { + $row->setLocation($data['parent_id'], 'first-child'); + } + } + } + + // Save old path + $catpath_old = $row->catpath; + + JFilterOutput::objectHTMLSafe($row->name); + + // Check if special characters of catname can be replaced for a valid catpath + // if resulting string is invalid set an error + $catpath = JoomFile::fixFilename($row->name); + if(JoomFile::checkValidFilename($catpath_old, $catpath) == false) + { + $this->setError(JText::_('COM_JOOMGALLERY_CATMAN_MSG_ERROR_INVALID_FOLDERNAME')); + return false; + } + + // Add the category id to catpath + $catpath .= '_' . $row->cid; + + if($row->parent_id > 1) + { + $parent_catpath = JoomHelper::getCatPath($row->parent_id); + $catpath = $parent_catpath . $catpath; + } + + // Move folders, only if the catpath has changed + if($catpath_old != $catpath && !$this->_moveFolders($catpath_old, $catpath)) + { + $this->setError(JText::_('COM_JOOMGALLERY_CATMAN_MSG_ERROR_MOVING_FOLDERS')); + return false; + } + // Update catpath in the database + $row->catpath = $catpath; + + // Modify catpath of all sub-categories in the database + $this->updateNewCatpath($row->cid, $catpath_old, $catpath); + } + else + { + // Check whether ordering has changed + if(isset($data['ordering']) && $data['ordering'] != $row->cid) + { + // Determine location in category tree + if($data['ordering'] == 'first-child' || $data['ordering'] == 'last-child') + { + $row->setLocation($data['parent_id'], $data['ordering']); + } + else + { + // Check whether the new reference category is a + // valid child category of the current parent category + $this->_db->setQuery($this->_db->getQuery(true) + ->select('cid') + ->from(_JOOM_TABLE_CATEGORIES) + ->where('parent_id = '.$row->parent_id) + ->where('cid = '.$data['ordering'])); + if($this->_db->loadResult()) + { + $row->setLocation($data['ordering'], 'after'); + } + } + } + } + + // Make sure the record is valid + if(!$row->check()) + { + $this->setError($row->getError()); + return false; + } + + // Store the entry to the database + if(!$row->store()) + { + $this->setError($row->getError()); + + return false; + } + + $this->_mainframe->triggerEvent('onContentAfterSave', array(_JOOM_OPTION.'.category', &$row, true)); + + return $row->cid; + } + + /** + * Method to perform batch operations on a category or a set of categories + * + * @param array $commands An array of commands to perform + * @param array $pks An array of category IDs + * @return boolean True on success, false otherwis + * @since 3.0 + */ + public function batch($commands, $pks) + { + // Sanitize user IDs + $pks = array_unique($pks); + JArrayHelper::toInteger($pks); + + // Remove any values of zero + if(array_search(0, $pks, true)) + { + unset($pks[array_search(0, $pks, true)]); + } + + if(empty($pks)) + { + $this->setError(JText::_('COM_JOOMGALLERY_COMMON_MSG_NO_CATEGORIES_SELECTED')); + + return false; + } + + $done = false; + + if($cmd = JArrayHelper::getValue($commands, 'move_copy')) + { + if($cmd == 'c') + { + $result = $this->batchCopy($commands['category_id'], $pks); + if(is_array($result)) + { + $pks = $result; + } + else + { + return false; + } + } + else + { + if($cmd == 'm' && !$this->batchMove($commands['category_id'], $pks)) + { + return false; + } + } + + $done = true; + } + + if(!empty($commands['assetgroup_id'])) + { + if(!$this->batchAccess($commands['assetgroup_id'], $pks)) + { + return false; + } + + $done = true; + } + + if(!empty($commands['language_id'])) + { + if(!$this->batchLanguage($commands['language_id'], $pks)) + { + return false; + } + + $done = true; + } + + if(!$done) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_INSUFFICIENT_BATCH_INFORMATION')); + + return false; + } + + return true; + } + + /** + * Batch access level changes for a group of categories + * + * @param int $value The new value matching an Asset Group ID + * @param array $pks An array of row IDs + * @return boolean True on success, false otherwise + * @since 3.0 + */ + protected function batchAccess($value, $pks) + { + $table = $this->getTable('joomgallerycategories'); + + foreach($pks as $pk) + { + $table->reset(); + $table->load($pk); + + if( $this->_user->authorise('core.edit', _JOOM_OPTION.'.category.'.$pk) + || ( + $table->owner == $this->_user->get('id') + && $table->owner != 0 + && $this->_user->authorise('core.edit.own', _JOOM_OPTION.'.category.'.$pk) + ) + ) + { + $table->load($pk); + $table->access = (int) $value; + + if(!$table->store()) + { + $this->setError($table->getError()); + + return false; + } + } + else + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); + + return false; + } + } + + return true; + } + + /** + * Batch copy items to a new category or current + * + * @param int $value The new parent category + * @param array $pks An array of category IDs + * @return mixed An array of new IDs on success, boolean false on failure + * @since 3.0 + */ + protected function batchCopy($value, $pks) + { + $categoryId = (int) $value; + + $table = $this->getTable('joomgallerycategories'); + $i = 0; + + // Check that the parent category exists + if($categoryId) + { + if(!$parent_category = $table->load($categoryId)) + { + if($error = $table->getError()) + { + $this->setError($error); + + return false; + } + else + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_MOVE_CATEGORY_NOT_FOUND')); + + return false; + } + } + } + + if(!$categoryId) + { + // Check that the user has create permissions in root + if(!$this->_user->authorise('core.create', _JOOM_OPTION)) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_CREATE')); + + return false; + } + + $categoryId = 1; + } + else + { + // Check that the user has create permissions + if(!$this->_user->authorise('core.create', _JOOM_OPTION.'.category.'.$categoryId) + && ( !$this->_user->authorise('joom.create.inown', _JOOM_OPTION.'.category.'.$categoryId) + || !$parent_category->owner + || $parent_category->owner != $this->_user->get('id') + ) + ) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_CREATE')); + + return false; + } + } + + foreach($pks as $pk) + { + $table->reset(); + + // Check that the row actually exists + if(!$table->load($pk)) + { + if($error = $table->getError()) + { + $this->setError($error); + + return false; + } + else + { + // Not fatal error + $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_BATCH_MOVE_ROW_NOT_FOUND', $pk)); + + continue; + } + } + + // Reset the ID and the alias (resetting catpath is + // necessary for that, too) because we are making a copy + $table->cid = 0; + $table->alias = ''; + $table->catpath = ''; + + // New parent category ID + $table->parent_id = $categoryId; + + // Set ordering + $table->setLocation($categoryId, 'last-child'); + + // Check the row + if(!$table->check()) + { + $this->setError($table->getError()); + + return false; + } + + JFilterOutput::objectHTMLSafe($table->name); + + // Check if special characters of catname can be replaced for a valid catpath + // if resulting string is invalid set an error + $catpath = JoomFile::fixFilename($table->name); + if(JoomFile::checkValidFilename($table->name, $catpath) == false) + { + $this->setError(JText::_('COM_JOOMGALLERY_CATMAN_MSG_ERROR_INVALID_FOLDERNAME')); + + return false; + } + + // Store the entry to the database in order to get the new ID + if(!$table->store()) + { + $this->setError($table->getError()); + + return false; + } + + if($table->parent_id > 1) + { + $parent_catpath = JoomHelper::getCatPath($table->parent_id); + $catpath = $parent_catpath . $catpath; + } + + // Add the category id to catpath + $catpath .= '_'.$table->cid; + + if(!$this->_createFolders($catpath)) + { + $this->setError(JText::_('COM_JOOMGALLERY_CATMAN_MSG_ERROR_CREATING_FOLDERS')); + + // Delete the just stored database entry + $table->delete(); + + return false; + } + + $table->catpath = $catpath; + + // Make sure the record is valid + if(!$table->check()) + { + $this->setError($table->getError()); + + return false; + } + + // Alter the title and alias (for preventing duplicates) + $data = $this->generateNewTitle($categoryId, $table->alias, $table->name); + $table->name = $data['0']; + $table->alias = $data['1']; + + // Store the entry to the database + if(!$table->store()) + { + $this-setError($table->getError()); + + return false; + } + + $this->_mainframe->triggerEvent('onContentAfterSave', array(_JOOM_OPTION.'.category', &$table, true)); + + // Get the new category ID + $newId = $table->cid; + + // Add the new ID to the array + $newIds[$i] = $newId; + $i++; + } + + return $newIds; + } + + /** + * Batch move categories to a new category + * + * @param int $value The new parent category ID + * @param array $pks An array of category IDs + * @return boolean True on success, false otherwise + * @since 3.0 + */ + protected function batchMove($value, $pks) + { + $categoryId = (int) $value; + + $table = $this->getTable('joomgallerycategories'); + + // Check that the parent category exists + if($categoryId) + { + if(!$parent_category = $table->load($categoryId)) + { + if($error = $table->getError()) + { + $this->setError($error); + + return false; + } + else + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_MOVE_CATEGORY_NOT_FOUND')); + + return false; + } + } + } + + if(!$categoryId) + { + // Check that the user has create permissions in root + if(!$this->_user->authorise('core.create', _JOOM_OPTION)) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_CREATE')); + + return false; + } + + $categoryId = 1; + } + else + { + // Check that the user has create permissions + if(!$this->_user->authorise('core.create', _JOOM_OPTION.'.category.'.$categoryId) + && ( !$this->_user->authorise('joom.create.inown', _JOOM_OPTION.'.category.'.$categoryId) + || !$parent_category->owner + || $parent_category->owner != $this->_user->get('id') + ) + ) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_CREATE')); + + return false; + } + } + + foreach($pks as $pk) + { + // Check that the category actually exists + if(!$table->load($pk)) + { + if($error = $table->getError()) + { + $this->setError($error); + + return false; + } + else + { + // Not fatal error + $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_BATCH_MOVE_ROW_NOT_FOUND', $pk)); + + continue; + } + } + + if(!$this->_user->authorise('core.edit', _JOOM_OPTION.'.category.'.$pk) + && ( !$this->_user->authorise('joom.edit.own', _JOOM_OPTION.'.category.'.$pk) + || !$table->owner + || $table->owner != $this->_user->get('id') + ) + ) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); + + return false; + } + + // New parent category ID + $table->parent_id = $categoryId; + + // Set ordering + $table->setLocation($categoryId, 'last-child'); + + // Save old path + $catpath_old = $table->catpath; + + JFilterOutput::objectHTMLSafe($table->name); + + // Check if special characters of catname can be replaced for a valid catpath + // if resulting string is invalid set an error + $catpath = JoomFile::fixFilename($table->name); + if(JoomFile::checkValidFilename($catpath_old, $catpath) == false) + { + $this->setError(JText::_('COM_JOOMGALLERY_CATMAN_MSG_ERROR_INVALID_FOLDERNAME')); + + return false; + } + + // Add the category ID to catpath + $catpath .= '_' . $table->cid; + + if($table->parent_id > 1) + { + $parent_catpath = JoomHelper::getCatPath($table->parent_id); + $catpath = $parent_catpath . $catpath; + } + + // Move folders, only if the catpath has changed + if($catpath_old != $catpath && !$this->_moveFolders($catpath_old, $catpath)) + { + $this->setError(JText::_('COM_JOOMGALLERY_CATMAN_MSG_ERROR_MOVING_FOLDERS')); + + return false; + } + + // Update catpath in the database + $table->catpath = $catpath; + + // Modify catpath of all sub-categories in the database + $this->updateNewCatpath($table->cid, $catpath_old, $catpath); + + // Make sure the record is valid + if(!$table->check()) + { + $this->setError($table->getError()); + + return false; + } + + // Store the entry to the database + if(!$table->store()) + { + $this-setError($table->getError()); + + return false; + } + } + + return true; + } + + /** + * Retrieves the data for creating the orderings drop down list + * + * @param int $parent Parent category which has to be included into the list independent of it's access state + * @return array An array of JHTML select options with the ordering numbers + * and the category names + * @since 1.5.5 + */ + public function getOrderings($parent = null) + { + if(empty($this->_orderings)) + { + $categories = JoomHelper::getAuthorisedCategories('core.create'); + + $allowed_categories = ''; + + // If the user is allowed to create main categories add '1' as an allowed parent category + if($this->_user->authorise('core.create', _JOOM_OPTION)) + { + $allowed_categories .= '1,'; + } + + foreach($categories as $category) + { + $allowed_categories .= $category->cid.','; + } + + if(!is_null($parent)) + { + $allowed_categories .= $parent; + } + else + { + $allowed_categories = trim($allowed_categories, ','); + } + + if(!$allowed_categories) + { + return array(); + } + + $query = $this->_db->getQuery(true); + $query->select('cid') + ->select('parent_id') + ->select('name') + ->from(_JOOM_TABLE_CATEGORIES) + ->where('parent_id IN ('.$allowed_categories.')') + ->where('lft > 0') + ->order('lft'); + $this->_db->setQuery($query); + if(!$this->_orderings = $this->_db->loadObjectList()) + { + $this->setError($this->_db->getError()); + + return array(); + } + } + + return $this->_orderings; + } + + /** + * Update of category path in the database for sub-categories + * if a parent category has been moved or the name has changed. + * + * Recursive call to each level of depth. + * + * @param string $catids_values ID(s) of the categories to update (comma separated) + * @param string $oldpath Former relative category path + * @param string $newpath New relative category path + * @return void + * @since 1.0.0 + */ + public function updateNewCatpath($catids_values, &$oldpath, &$newpath) + { + // Query for sub-categories with parent in $catids_values + $query = $this->_db->getQuery(true) + ->select('cid') + ->from(_JOOM_TABLE_CATEGORIES) + ->where('parent_id IN ('.$catids_values.')'); + $this->_db->setQuery($query); + + $subcatids = $this->_db->loadColumn(); + + if($this->_db->getErrorNum()) + { + JError::raiseWarning(500, $this->_db->getErrorMsg()); + } + + // Nothing found, return + if(!count($subcatids)) + { + return; + } + + $row = JTable::getInstance('joomgallerycategories', 'Table'); + foreach($subcatids as $subcatid) + { + $row->load($subcatid); + $catpath = $row->catpath; + + // Replace former category path with new one + $catpath = str_replace($oldpath.'/', $newpath.'/', $catpath); + + // Then save it + $row->catpath = $catpath; + if(!$row->store()) + { + JError::raiseError(500, $row->getError()); + } + } + + // Split the array in comma separated string + $catids_values = implode (',', $subcatids); + + // Call again with sub-categories as parent + $this->updateNewCatpath($catids_values, $oldpath, $newpath); + } + + /** + * Creates the folders for a category + * + * @param string The category path for the category + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + protected function _createFolders($catpath) + { + $catpath = JPath::clean($catpath); + + // Create the folder of the category for the original images + if(!JFolder::create($this->_ambit->get('orig_path').$catpath)) + { + // If not successfull + return false; + } + else + { + // Copy an index.html file into the new folder + JoomFile::copyIndexHtml($this->_ambit->get('orig_path').$catpath); + + // Create the folder of the category for the detail images + if(!JFolder::create($this->_ambit->get('img_path').$catpath)) + { + // If not successful + JFolder::delete($this->_ambit->get('orig_path').$catpath); + return false; + } + else + { + // Copy an index.html file into the new folder + JoomFile::copyIndexHtml($this->_ambit->get('img_path').$catpath); + + // Create the folder of the category for the thumbnails + if(!JFolder::create($this->_ambit->get('thumb_path').$catpath)) + { + // If not successful + JFolder::delete($this->_ambit->get('orig_path').$catpath); + JFolder::delete($this->_ambit->get('img_path').$catpath); + return false; + } + else + { + // Copy an index.html file into the new folder + JoomFile::copyIndexHtml($this->_ambit->get('thumb_path').$catpath); + } + } + } + + return true; + } + + /** + * Moves folders of an existing category + * + * @param string $src The source category path + * @param string $dest The destination category path + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + protected function _moveFolders($src, $dest) + { + $orig_src = JPath::clean($this->_ambit->get('orig_path').$src); + $orig_dest = JPath::clean($this->_ambit->get('orig_path').$dest); + $img_src = JPath::clean($this->_ambit->get('img_path').$src); + $img_dest = JPath::clean($this->_ambit->get('img_path').$dest); + $thumb_src = JPath::clean($this->_ambit->get('thumb_path').$src); + $thumb_dest = JPath::clean($this->_ambit->get('thumb_path').$dest); + + // Move the folder of the category for the original images + $return = JFolder::move($orig_src, $orig_dest); + if($return !== true) + { + // If not successfull + JError::raiseWarning(100, $return); + return false; + } + else + { + // Move the folder of the category for the detail images + $return = JFolder::move($img_src, $img_dest); + if($return !== true) + { + // If not successful + JFolder::move($orig_dest, $orig_src); + JError::raiseWarning(100, $return); + return false; + } + else + { + // Move the folder of the category for the thumbnails + $return = JFolder::move($thumb_src, $thumb_dest); + if($return !== true) + { + // If not successful + JFolder::move($orig_dest, $orig_src); + JFolder::move($img_dest, $img_src); + JError::raiseWarning(100, $return); + return false; + } + } + } + + return true; + } + + /** + * Method to validate the form data + * + * @param object $form The form to validate against + * @param array $data The data to validate + * @return mixed Array of filtered data if valid, false otherwise + * @since 2.0 + */ + protected function _validate($form, $data) + { + // Filter and validate the form data + $data = $form->filter($data); + $return = $form->validate($data); + + // Check for an error + if(JError::isError($return)) + { + $this->setError($return->getMessage()); + return false; + } + + // Check the validation results + if ($return === false) + { + // Get the validation messages from the form + foreach($form->getErrors() as $message) + { + $this->setError(JText::_($message)); + } + return false; + } + + return $data; + } + + /** + * Method to change the name and the alias if there exist already the same + * + * @param int The parent category ID + * @param string The alias of the category + * @param string The name of the category + * @return array Holds the new name and alias + * @since 2.0 + */ + function generateNewTitle(&$parent_id, &$alias, &$title) + { + // Alter the name and the alias + $table = $this->getTable('joomgallerycategories'); + while($table->load(array('alias' => $alias, 'parent_id' => $parent_id))) + { + $m = null; + if(preg_match('#-(\d+)$#', $alias, $m)) + { + $alias = preg_replace('#-(\d+)$#', '-'.($m[1] + 1).'', $alias); + } + else + { + $alias .= '-2'; + } + if(preg_match('#\((\d+)\)$#', $title, $m)) + { + $title = preg_replace('#\(\d+\)$#', '('.($m[1] + 1).')', $title); + } + else + { + $title .= ' (2)'; + } + } + + return array($title, $alias); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/models/comments.php b/deployed/joomgallery/administrator/components/com_joomgallery/models/comments.php new file mode 100644 index 00000000..641ef612 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/models/comments.php @@ -0,0 +1,593 @@ +filter_fields = array( + 'cmtid', 'c.cmtid', + 'user', + 'cmttext', 'c.cmttext', + 'published', 'c.published', + 'approved', 'c.approved', + 'cmtip', 'c.cmtip', + 'i.imgtitle', + 'cmtdate', 'c.cmtdate', + 'state' + ); + } + + /** + * Retrieves the comments data + * + * @return array Array of objects containing the comments data from the database + * @since 1.5.5 + */ + public function getComments() + { + // Lets load the data if it doesn't already exist + if(empty($this->_comments)) + { + $query = $this->_buildQuery(); + $this->_comments = $this->_getList($query, $this->getStart(), $this->getState('list.limit')); + + foreach($this->_comments as $key => $comment) + { + if($comment->userid > 0) + { + $this->_comments[$key]->cmtname = JHTML::_('joomgallery.displayname', $comment->userid); + } + + $this->_comments[$key]->cmttext = JoomHelper::processText($comment->cmttext); + } + } + + return $this->_comments; + } + + /** + * Function to get the active filters + * + * @return array Associative array in the format: array('filter_published' => 0) + * + * @since 3.2.3 + */ + public function getActiveFilters() + { + $activeFilters = array(); + + if (!empty($this->filter_fields)) + { + foreach ($this->filter_fields as $filter) + { + $filterName = 'filter.' . $filter; + + if (property_exists($this->state, $filterName) && (!empty($this->state->{$filterName}) || is_numeric($this->state->{$filterName}))) + { + $activeFilters[$filter] = $this->state->get($filterName); + } + } + } + + return $activeFilters; + } + + /** + * Method to get the pagination object for the list. + * This method uses 'getTotel', 'getStart' and the current + * list limit of this view. + * + * @return object A pagination object + * @since 2.0 + */ + public function getPagination() + { + return new JPagination($this->getTotal(), $this->getStart(), $this->getState('list.limit')); + } + + /** + * Method to get the total number of comments + * + * @return int The total number of comments in the gallery + * @since 1.5.5 + */ + public function getTotal() + { + // Lets load the comments number if it doesn't already exist + if(empty($this->_total)) + { + $query = $this->_buildQuery(); + $this->_total = $this->_getListCount($query); + } + + return $this->_total; + } + + /** + * Method to get the starting number of items for the data set. + * + * @return int The starting number of items available in the data set. + * @since 2.0 + */ + public function getStart() + { + $start = $this->getState('list.start'); + $limit = $this->getState('list.limit'); + $total = $this->getTotal(); + if($start > $total - $limit) + { + $start = max(0, (int)(ceil($total / $limit) - 1) * $limit); + } + + return $start; + } + + /** + * Get the filter form + * + * @param array $data data + * @param boolean $loadData load current data + * + * @return JForm/false the JForm object or false + * + * @since 3.2.3 + */ + public function getFilterForm($data = array(), $loadData = true) + { + return $this->loadForm(_JOOM_OPTION . '.filter_comments', 'filter_comments', array('control' => '', 'load_data' => $loadData)); + } + + /** + * Method to get a form object. + * + * @param string $name The name of the form. + * @param string $source The form source. Can be XML string if file flag is set to false. + * @param array $options Optional array of options for the form creation. + * @param boolean $clear Optional argument to force load a new form. + * @param string $xpath An optional xpath to search for the fields. + * + * @return mixed JForm object on success, False on error. + * + * @see JForm + * @since 3.2.3 + */ + protected function loadForm($name, $source = null, $options = array(), $clear = false, $xpath = false) + { + // Handle the optional arguments. + $options['control'] = JArrayHelper::getValue($options, 'control', false); + + // Get the form. + JForm::addFormPath(JPATH_COMPONENT . '/models/forms'); + JForm::addFieldPath(JPATH_COMPONENT . '/models/fields'); + + try + { + $form = JForm::getInstance($name, $source, $options, false, $xpath); + + if(isset($options['load_data']) && $options['load_data']) + { + // Get the data for the form. + $data = $this->loadFormData(); + } + else + { + $data = array(); + } + + // Load the data into the form after the plugins have operated. + $form->bind($data); + } + catch(Exception $e) + { + $this->setError($e->getMessage()); + + return false; + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 3.2.3 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = JFactory::getApplication()->getUserState('joom.comments', new stdClass); + + // Pre-fill the list options + if (!property_exists($data, 'list')) + { + $data->list = array( + 'direction' => $this->state->{'list.direction'}, + 'limit' => $this->state->{'list.limit'}, + 'ordering' => $this->state->{'list.ordering'}, + 'start' => $this->state->{'list.start'} + ); + } + + return $data; + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @param string An optional ordering field. + * @param string An optional direction (asc|desc). + * @return void + * @since 2.0 + */ + protected function populateState($ordering = 'c.cmtdate', $direction = 'desc') + { + // Receive & set filters + $filters = $this->getUserStateFromRequest('joom.comments.filter', 'filter', array('search' => null, 'state' => ''), 'array'); + + if($filters) + { + foreach($filters as $name => $value) + { + $this->setState('filter.' . $name, $value); + + if($value) + { + $this->setState('filter.inuse', 1); + } + } + } + + $limit = 0; + + // Receive & set list options + $list = $this->getUserStateFromRequest('joom.comments.list', 'list', + array('ordering' => $ordering, 'direction' => $direction, 'fullordering' => $ordering . ' ' . $direction, + 'limit' => $this->_mainframe->getCfg('list_limit'), 'start' => 0), 'array'); + + if($list) + { + foreach($list as $name => $value) + { + // Extra validations + switch($name) + { + case 'fullordering': + $orderingParts = explode(' ', $value); + + if(count($orderingParts) >= 2) + { + // Latest part will be considered the direction + $fullDirection = end($orderingParts); + + if(in_array(strtoupper($fullDirection), array('ASC', 'DESC', ''))) + { + $this->setState('list.direction', $fullDirection); + } + + unset($orderingParts[count($orderingParts) - 1]); + + // The rest will be the ordering + $fullOrdering = implode(' ', $orderingParts); + + if(in_array($fullOrdering, $this->filter_fields)) + { + $this->setState('list.ordering', $fullOrdering); + } + } + else + { + $this->setState('list.ordering', $ordering); + $this->setState('list.direction', $direction); + } + break; + case 'ordering': + if(!in_array($value, $this->filter_fields)) + { + $value = $ordering; + } + break; + + case 'direction': + if(!in_array(strtoupper($value), array('ASC', 'DESC', ''))) + { + $value = $direction; + } + break; + + case 'limit': + $limit = $value; + break; + + // Just to keep the default case + default: + $value = $value; + break; + } + + $this->setState('list.' . $name, $value); + } + + $value = $this->getUserStateFromRequest('joom.comments.limitstart', 'limitstart', 0); + $limitstart = ($limit != 0 ? (floor($value / $limit) * $limit) : 0); + $this->setState('list.start', $limitstart); + } + } + + /** + * Returns the query for loading all comments + * + * @return string The query to be used to retrieve the rows from the database + * @since 1.5.5 + */ + protected function _buildQuery() + { + // Create a new query object + $query = $this->_db->getQuery(true); + + // Select the required fields from the table + $query->select('c.*') + ->from(_JOOM_TABLE_COMMENTS.' AS c'); + + // Join over the images + $query->select('i.id, i.imgtitle, i.imgthumbname, i.catid, i.owner') + ->join('LEFT', _JOOM_TABLE_IMAGES.' AS i ON i.id = c.cmtpic'); + + // Join over the users + $query->select('u.username AS user') + ->join('LEFT', '#__users AS u ON u.id = c.userid'); + + /*// Filter by owner + $owner = $this->getState('filter.owner'); + if($owner !== '') + { + $query->where('a.owner = '.(int) $owner); + }*/ + + // Filter by state + $published = $this->getState('filter.state'); + switch($published) + { + case 1: + // Published + $query->where('c.published = 1'); + break; + case 2: + // Not published + $query->where('c.published = 0'); + break; + case 3: + // Approved + $query->where('c.approved = 1'); + break; + case 4: + // Not approved / rejected + $query->where('c.approved = 0'); + break; + default: + // No filter by state + break; + } + + // Filter by search + $search = $this->getState('filter.search'); + if(!empty($search)) + { + if(stripos($search, 'id:') === 0) + { + $query->where('c.cmtid = '.(int) substr($search, 3)); + } + else + { + if(stripos($search, 'author:') === 0) + { + $search = $this->_db->Quote('%'.$this->_db->escape(substr($search, 7), true).'%'); + $query->where('(u.name LIKE '.$search.' OR u.username LIKE '.$search.')'); + } + else + { + $search = $this->_db->Quote('%'.$this->_db->escape($search, true).'%'); + $query->where('LOWER(c.cmttext) LIKE '.$search); + } + } + } + + // Add the order clause + $query->order($this->_db->escape($this->getState('list.ordering', 'c.cmtdate')).' '.$this->_db->escape($this->getState('list.direction', 'DESC'))); + + if($this->getState('list.ordering') == 'user') + { + $query->order('c.cmtname '.$this->getState('list.direction', 'ASC')); + } + + return $query; + } + + /** + * Method to delete one or more comments + * + * @return int The number of successfully deleted comments, boolean false if an error occured + * @since 1.5.5 + */ + public function delete() + { + $cids = JRequest::getVar('cid', array(0), 'post', 'array'); + + $row = $this->getTable('joomgallerycomments'); + + if(count($cids)) + { + foreach($cids as $cid) + { + if (!$row->delete($cid)) + { + $this->setError($row->getErrorMsg()); + return false; + } + } + + return count($cids); + } + + return false; + } + + /** + * Method to publish, unpublish, approve or reject one or more comments + * + * @param array $cid Array of comment IDs to perform the task on + * @param int $publish 1 for publishing or approving, 0 for unpublishing or rejecting + * @param string $task The task to perform ('publish' or 'approve') + * @return int The number of successfully processed comments, false otherwise + * @since 1.5.5 + */ + public function publish($cid, $publish = 1, $task = 'publish') + { + JArrayHelper::toInteger($cid); + $cids = implode(',', $cid); + + $column = 'approved'; + if($task == 'publish') + { + $column = 'published'; + } + + $query = $this->_db->getQuery(true) + ->update(_JOOM_TABLE_COMMENTS) + ->set($column.' = '.(int) $publish) + ->where('cmtid IN ('.$cids.' )'); + $this->_db->setQuery($query); + if(!$this->_db->query()) + { + return false; + } + + // Message about new comment to image owner + if($column == 'approved' && $publish && $this->_config->get('jg_msg_comment_toowner')) + { + require_once(JPATH_COMPONENT_SITE.'/helpers/messenger.php'); + $messenger = new JoomMessenger(); + + foreach($cid as $id) + { + // Load comment data + $comment = $this->getTable('joomgallerycomments'); + $comment->load($id); + + if(!$name = $comment->cmtname) + { + $user = JFactory::getUser($comment->userid); + $name = $this->_config->get('jg_realname') ? $this->_user->get('name') : $this->_user->get('username'); + } + + // Load image data + $image = $this->getTable('joomgalleryimages'); + $image->load($comment->cmtpic); + + if($image->owner && $image->owner != $comment->userid) + { + $mode = $messenger->getModeData('comment'); + $message = array( + 'from' => $this->_user->get('id'), + 'subject' => JText::_('COM_JOOMGALLERY_MESSAGE_NEW_COMMENT_TO_OWNER_SUBJECT'), + 'body' => JText::sprintf('COM_JOOMGALLERY_MESSAGE_NEW_COMMENT_TO_OWNER_BODY', $name, $image->imgtitle, $image->id), + 'type' => $mode['type'] + ); + + $message['recipient'] = $image->owner; + + $messenger->send($message); + } + } + } + + return count($cid); + } + + /** + * Gets the value of a user state variable and sets it in the session + * This is the same as the method in JApplication except that this also can optionally + * force you back to the first page when a filter has changed + * + * @param string $key The key of the user state variable + * @param string $request The name of the variable passed in a request + * @param string $default The default value for the variable if not found (optional) + * @param string $type Filter for the variable, for valid values see {@link JFilterInput::clean()} (optional) + * @param boolean $resetPage If true, the limitstart in request is set to zero if the state has changed + * @return The requested user state + * @since 2.0 + */ + public function getUserStateFromRequest($key, $request, $default = null, $type = 'none', $resetPage = true) + { + $app = JFactory::getApplication(); + + $old_state = $app->getUserState($key); + $cur_state = (!is_null($old_state)) ? $old_state : $default; + $new_state = JRequest::getVar($request, null, 'default', $type); + + if($cur_state != $new_state && !is_null($new_state) && !is_null($old_state) && $resetPage) + { + JRequest::setVar('limitstart', 0); + } + + // Save the new value only if it was set in this request. + if($new_state !== null) + { + $app->setUserState($key, $new_state); + } + else + { + $new_state = $cur_state; + } + + return $new_state; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/models/config.php b/deployed/joomgallery/administrator/components/com_joomgallery/models/config.php new file mode 100644 index 00000000..04428525 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/models/config.php @@ -0,0 +1,130 @@ +jg_impath)) + { + $execstring = $config->get('jg_impath').'convert -version'; + } + else + { + $execstring = 'convert -version'; + } + + @exec($execstring, $output, $status); + + if(count($output) == 0) + { + return 0; + } + else + { + return $output[0]; + } + } + + /** + * Returns the title of the current config row + * + * @return string The title of the current config row + * @since 2.0 + */ + public function getConfigTitle() + { + $query = $this->_db->getQuery(true) + ->select('g.title') + ->from(_JOOM_TABLE_CONFIG.' AS c') + ->from('#__usergroups AS g') + ->where('c.group_id = g.id') + ->where('c.id = '.JRequest::getInt('id')); + $this->_db->setQuery($query); + + return $this->_db->loadResult(); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/models/configs.php b/deployed/joomgallery/administrator/components/com_joomgallery/models/configs.php new file mode 100644 index 00000000..33f46887 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/models/configs.php @@ -0,0 +1,560 @@ +filter_fields = array( + 'id', 'c.id', + 'title', 'g.title', + 'lft', 'g.lft', + 'ordering', 'c.ordering' + ); + } + + /** + * Retrieves the data of the config rows + * + * @access public + * @return array Array of objects containing the config rows from the database + * @since 2.0 + */ + function getConfigs() + { + // Let's load the data if it doesn't already exist + if(empty($this->_configs)) + { + // Get the data of the categories which will actually be displayed + $query = $this->_buildQuery(); + $this->_db->setQuery($query, $this->getState('list.start'), $this->getState('list.limit')); + $configs = $this->_db->loadObjectList('group_id'); + + $this->_configs = array(); + foreach($configs as $key => $config) + { + // If there is at least one config row with a higher ordering value which belongs + // to a parent user group the current config row can/will never be applied to a user + if($this->getActiveParentConfigs($config->group_id, $config->ordering)) + { + $config->usergroups = false; + + continue; + } + + // With the following code we want to get all user groups + // for which the current config row applies. + $subgroups = $this->getTree($config->group_id); + $config->usergroups = array(); + $removing = false; + foreach($subgroups as $key => $subgroup) + { + // If the removing flag is set we won't store user groups + // which are children of the group stored in $removing + if($removing) + { + if($subgroup->rgt > $removing) + { + // If rgt of current group is greater than the + // stored one the complete sub-tree was parsed + $removing = false; + } + else + { + continue; + } + } + + // If there is a config row for the current user group with a higher ordering value + // that one will be used for the current user group and all of its sub-groups + if(isset($configs[$subgroup->id]) && $configs[$subgroup->id]->ordering > $config->ordering) + { + $removing = $subgroup->rgt; + + continue; + } + + // If we reach this point the current config row will + // be applied to the current user group, so store it + $config->usergroups[] = $subgroup->title; + } + + // Prepend the user group the config row belongs to + array_unshift($config->usergroups, $config->title); + } + + $this->_configs = $configs; + } + + return $this->_configs; + } + + /** + * Retrieves the most important data of each of the config rows + * + * @access public + * @return array Array of objects containing the config rows from the database + * @since 2.1 + */ + function getAllConfigs() + { + // Let's load the data if it doesn't already exist + if(empty($this->_allconfigs)) + { + // Create a new query object + $query = $this->_db->getQuery(true); + + // Select the required fields from the table + $query->select('c.id, c.group_id, c.ordering') + ->from(_JOOM_TABLE_CONFIG.' AS c'); + + // Join over the user groups + $query->select('g.title') + ->leftJoin('#__usergroups AS g ON g.id = c.group_id'); + + $this->_db->setQuery($query); + + $this->_allconfigs = $this->_db->loadObjectList(); + } + + return $this->_allconfigs; + } + + /** + * Method to get all available usergroups for which there isn't a config row yet + * + * @return array Array of all available usergroups without an existing config row + * @since 2.0 + */ + public function getUsergroups() + { + $configs = $this->getAllConfigs(); + + $group_ids = array(); + foreach($configs as $config) + { + $group_ids[] = $config->group_id; + } + + $query = $this->_db->getQuery(true) + ->select('a.id AS value, a.title AS text, COUNT(DISTINCT b.id) AS level') + ->from('#__usergroups AS a') + ->leftJoin('#__usergroups AS b ON a.lft > b.lft AND a.rgt < b.rgt') + ->where('a.id NOT IN ('.implode(',', $group_ids).')') + ->group('a.id') + ->order('a.lft ASC'); + $this->_db->setQuery($query); + + try + { + $options = $this->_db->loadObjectList(); + } + catch(DatabaseException $e) + { + $this->setError($this->_db->getErrorMsg()); + + return array(); + } + + foreach($options as $key => $option) + { + $option->text = str_repeat('- ', $option->level).$option->text; + } + + return $options; + } + + /** + * Returns the number of config rows for parent groups of a specific user group + * which have a higher ordering value than that user group + * + * @param int The ID of the user group + * @param int The ordering value of the user group + * @return int The number of config rows which match the conditions above + * @since 2.0 + */ + protected function getActiveParentConfigs($group, $ordering) + { + $query = $this->_db->getQuery(true) + ->select('COUNT(c.id)') + ->from('#__usergroups AS a') + ->leftJoin('#__usergroups AS b ON b.lft BETWEEN a.lft AND a.rgt') + ->leftJoin(_JOOM_TABLE_CONFIG.' AS c ON a.id = c.group_id') + ->where('b.id = '.(int) $group) + ->where('c.ordering > '.(int) $ordering) + ->order('a.lft'); + $this->_db->setQuery($query); + + try + { + $subgroups = $this->_db->loadResult(); + } + catch(DatabaseException $e) + { + $this->setError($e->getMessage()); + + return array(); + } + + return $subgroups; + } + + /** + * Returns the sub-tree of groups for a specific user group + * + * @param int The ID of the user group + * @return array The sub-tree of the specified group + * @since 2.0 + */ + protected function getTree($group) + { + $query = $this->_db->getQuery(true) + ->select('a.id, a.rgt, a.title, c.id AS config_id, c.ordering') + ->from('#__usergroups AS a') + ->leftJoin('#__usergroups AS b ON a.lft > b.lft AND a.lft < b.rgt') + ->leftJoin(_JOOM_TABLE_CONFIG.' AS c ON a.id = c.group_id') + ->where('b.id = '.(int) $group) + ->order('a.lft'); + $this->_db->setQuery($query); + + try + { + $subgroups = $this->_db->loadObjectList(); + } + catch(DatabaseException $e) + { + $this->setError($e->getMessage()); + + return array(); + } + + return $subgroups; + } + + /** + * Method to get the pagination object for the list. + * This method uses 'getTotel', 'getStart' and the current + * list limit of this view. + * + * @return object A pagination object + * @since 2.0 + */ + function getPagination() + { + jimport('joomla.html.pagination'); + return new JPagination($this->getTotal(), $this->getStart(), $this->getState('list.limit')); + } + + /** + * Method to get the total number of categories + * + * @access public + * @return int The total number of categories + * @since 2.0 + */ + function getTotal() + { + // Let's load the number of categories if it doesn't already exist + if(empty($this->_total)) + { + $query = $this->_buildQuery(); + $this->_total = $this->_getListCount($query); + } + + return $this->_total; + } + + /** + * Method to get the starting number of items for the data set. + * + * @return int The starting number of items available in the data set. + * @since 2.0 + */ + public function getStart() + { + $start = $this->getState('list.start'); + $limit = $this->getState('list.limit'); + $total = $this->getTotal(); + if($start > $total - $limit) + { + $start = max(0, (int)(ceil($total / $limit) - 1) * $limit); + } + + return $start; + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @param string An optional ordering field. + * @param string An optional direction (asc|desc). + * @return void + * @since 2.0 + */ + protected function populateState($ordering = 'c.ordering', $direction = 'ASC') + { + $search = $this->getUserStateFromRequest('joom.configs.filter.search', 'filter_search'); + $this->setState('filter.search', $search); + + $type = $this->getUserStateFromRequest('joom.configs.filter.type', 'filter_type', ''); + $this->setState('filter.type', $type); + + $value = $this->getUserStateFromRequest('global.list.limit', 'limit', $this->_mainframe->getCfg('list_limit')); + $limit = $value; + $this->setState('list.limit', $limit); + + $value = $this->getUserStateFromRequest('joom.configs.limitstart', 'limitstart', 0); + $limitstart = ($limit != 0 ? (floor($value / $limit) * $limit) : 0); + $this->setState('list.start', $limitstart); + + // Check if the ordering field is in the white list, otherwise use the incoming value + $value = $this->getUserStateFromRequest('joom.configs.ordercol', 'filter_order', $ordering); + if(!in_array($value, $this->filter_fields)) + { + $value = $ordering; + $this->_mainframe->setUserState('joom.configs.ordercol', $value); + } + + $this->setState('list.ordering', $value); + + // Check if the ordering direction is valid, otherwise use the incoming value + $value = $this->getUserStateFromRequest('joom.configs.orderdirn', 'filter_order_Dir', $direction); + if(!in_array(strtoupper($value), array('ASC', 'DESC', ''))) + { + $value = $direction; + $this->_mainframe->setUserState('joom.configs.orderdirn', $value); + } + + $this->setState('list.direction', $value); + } + + /** + * Returns the query for listing the config rows + * + * @return object The query to be used to retrieve the config rows data from the database + * @since 2.0 + */ + protected function _buildQuery() + { + // Create a new query object + $query = $this->_db->getQuery(true); + + // Select the required fields from the table + $query->select('c.id, c.group_id, c.ordering') + ->from(_JOOM_TABLE_CONFIG.' AS c'); + + // Join over the user groups + $query->select('g.title') + ->leftJoin('#__usergroups AS g ON g.id = c.group_id'); + + // Add the level in the tree. + $query->select('COUNT(DISTINCT g2.id) AS level') + ->leftJoin('#__usergroups AS g2 ON g.lft > g2.lft AND g.rgt < g2.rgt') + ->group('g.id'); + + // Filter by search + $search = $this->getState('filter.search'); + if(!empty($search)) + { + if(stripos($search, 'id:') === 0) + { + $query->where('c.id = '.(int) substr($search, 3)); + } + else + { + $search = $this->_db->Quote('%'.$this->_db->escape($search, true).'%'); + $query->where('LOWER(g.title) LIKE '.$search); + } + } + + // Add the order clause + $query->order($this->_db->escape($this->getState('list.ordering', 'c.ordering')).' '.$this->_db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } + + /** + * Propagates changes in settings to all config rows + * + * @param array Array of changed config settings + * @param int ID of the initially changed config row + * @param boolean Determines whether all changes shall be propagated (true) or only the global ones (false) + * @return boolean True on success, false otherwise + * @since 2.0 + */ + public function propagateChanges($data, $id = 1, $all = false) + { + // Sanitise variables + $data = (array) $data; + if(!$id) + { + $id = 1; + } + + $global_settings = $this->_getGlobalSettings(); + + // Unset fields which must not be changed + foreach($data as $key => $value) + { + if( strpos($key, 'jg_') !== 0 + || (!$all && !in_array($key, $global_settings))) + { + unset($data[$key]); + } + } + + if(!count($data)) + { + // Nothing to do + return true; + } + + // Get the IDs of all config rows except the initially changed one + $query = $this->_db->getQuery(true) + ->select('id') + ->from(_JOOM_TABLE_CONFIG) + ->where('id != '.$id); + $this->_db->setQuery($query); + + try + { + $ids = $this->_db->loadColumn(); + } + catch(DatabaseException $e) + { + $this->setError($this->_db->getErrorMsg()); + + return false; + } + + if(!count($ids)) + { + // Nothing to do + return true; + } + + $config = JoomConfig::getInstance('admin'); + + foreach($ids as $config_id) + { + if(!$config->save($data, $config_id)) + { + $this->setError($config->getError()); + + return false; + } + } + + return true; + } + + /** + * Returns the names of settings which can't be different in different config rows + * + * @return array An array of global settings + * @since 2.0 + */ + protected function _getGlobalSettings() + { + return array('jg_paththumbs', 'jg_pathimages', 'jg_pathoriginalimages', 'jg_pathtemp', + 'jg_filenamewithjs', 'jg_filenamereplace', + 'jg_thumbcreation', 'jg_fastgd2thumbcreation', 'jg_impath', 'jg_resizetomaxwidth', 'jg_maxwidth', 'jg_picturequality', 'jg_useforresizedirection', 'jg_cropposition', 'jg_thumbwidth', 'jg_thumbheight', 'jg_thumbquality', + 'jg_download_unreg', + 'jg_anoncomment', 'jg_namedanoncomment', 'jg_anonapprovecom', + 'jg_report_unreg', + 'jg_showuserpanel_unreg', + 'jg_showcommentsunreg', + 'jg_nameshields_unreg', 'jg_show_nameshields_unreg', + 'jg_usefavouritesforpubliczip' + ); + } + + /** + * Gets the value of a user state variable and sets it in the session + * This is the same as the method in JApplication except that this also can optionally + * force you back to the first page when a filter has changed + * + * @param string The key of the user state variable. + * @param string The name of the variable passed in a request. + * @param string The default value for the variable if not found. Optional. + * @param string Filter for the variable, for valid values see {@link JFilterInput::clean()}. Optional. + * @param boolean If true, the limitstart in request is set to zero + * @return The requested user state. + * @since 2.0 + */ + public function getUserStateFromRequest($key, $request, $default = null, $type = 'none', $resetPage = true) + { + $app = JFactory::getApplication(); + $old_state = $app->getUserState($key); + $cur_state = (!is_null($old_state)) ? $old_state : $default; + $new_state = JRequest::getVar($request, null, 'default', $type); + + if (($cur_state != $new_state) && ($resetPage)){ + JRequest::setVar('limitstart', 0); + } + + // Save the new value only if it was set in this request. + if ($new_state !== null) { + $app->setUserState($key, $new_state); + } + else { + $new_state = $cur_state; + } + + return $new_state; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/models/control.php b/deployed/joomgallery/administrator/components/com_joomgallery/models/control.php new file mode 100644 index 00000000..790b5b2e --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/models/control.php @@ -0,0 +1,188 @@ +_db->getQuery(true) + ->select('*') + ->from('#__menu') + ->where('parent_id != 1') + ->where("menutype = 'main'"); + + $where[] = "link LIKE 'index.php?option=com_joomgallery&controller=images%'"; + $where[] = "link LIKE 'index.php?option=com_joomgallery&controller=categories%'"; + $where[] = "link LIKE 'index.php?option=com_joomgallery&controller=comments%'"; + $where[] = "link LIKE 'index.php?option=com_joomgallery&controller=migration%'"; + $where[] = "link LIKE 'index.php?option=com_joomgallery&controller=help%'"; + + $canDo = JoomHelper::getActions(); + if($this->_config->get('jg_disableunrequiredchecks') || $canDo->get('joom.upload') || count(JoomHelper::getAuthorisedCategories('joom.upload'))) + { + $where[] = "link LIKE 'index.php?option=com_joomgallery&controller=upload%'"; + $where[] = "link LIKE 'index.php?option=com_joomgallery&controller=ajaxupload%'"; + $where[] = "link LIKE 'index.php?option=com_joomgallery&controller=batchupload%'"; + $where[] = "link LIKE 'index.php?option=com_joomgallery&controller=ftpupload%'"; + $where[] = "link LIKE 'index.php?option=com_joomgallery&controller=jupload%'"; + } + if($canDo->get('core.admin')) + { + $where[] = "link LIKE 'index.php?option=com_joomgallery&controller=config%'"; + $where[] = "link LIKE 'index.php?option=com_joomgallery&controller=cssedit%'"; + $where[] = "link LIKE 'index.php?option=com_joomgallery&controller=maintenance%'"; + } + + $query->where('('.implode(' OR ', $where).')') + ->order('id'); + + return $query; + } + + /** + * Retrieves the data of the backend menu entries for JoomGallery + * + * @return array An array of objects containing the data of the menu entries from the database + * @since 1.5.5 + */ + public function getData() + { + // Lets load the data if it doesn't already exist + if(empty($this->_data)) + { + $query = $this->_buildQuery(); + $this->_data = $this->_getList($query); + } + + return $this->_data; + } + + /** + * Retrieves the images data + * + * @param string $orderby The database ordering clause + * @param boolean $approved Flag, if only approved images should queried + * @param int $limit Query limit + * @param string $where Additional database where clause + * @return array Array of objects containing the images data from the database + * @since 3.0 + */ + public function getImages($orderby = 'a.hits desc', $approved = true, $limit = 5, $where = null) + { + // Create a new query object + $query = $this->_db->getQuery(true); + + // Select the required fields from the table + $query->select('a.*') + ->from(_JOOM_TABLE_IMAGES.' AS a'); + + // Join over the categories + $query->select('c.cid AS category, c.name AS category_name') + ->leftJoin(_JOOM_TABLE_CATEGORIES.' AS c ON c.cid = a.catid'); + + // Join over the categories again in order to check access levels + if(!$this->_user->authorise('core.admin')) + { + $query->leftJoin(_JOOM_TABLE_CATEGORIES.' AS p ON c.lft BETWEEN p.lft AND p.rgt') + ->select('c.level') + ->where('p.access IN ('.implode(',', $this->_user->getAuthorisedViewLevels()).')') + ->group('a.id') + ->having('COUNT(p.cid) > c.level') + + // Access level check for the image and the category the image is in + ->where('a.access IN ('.implode(',', $this->_user->getAuthorisedViewLevels()).')') + ->where('c.access IN ('.implode(',', $this->_user->getAuthorisedViewLevels()).')'); + } + + $query->where('a.published = 1'); + $query->where('a.approved = '.($approved ? '1' : '0')); + + if(!empty($where)) + { + $query->where($where); + } + + $query->order($orderby); + + return $this->_getList($query, 0, $limit); + } + + /** + * Retrieves the images data + * + * @param string $orderby The database ordering clause + * @param boolean $approved Flag, if only approved comments should queried + * @param int $limit Query limit + * @return array Array of objects containing the images data from the database + * @since 3.0 + */ + public function getComments($orderby = 'c.cmtdate desc', $approved = true, $limit = 5) + { + // Create a new query object + $query = $this->_db->getQuery(true); + + // Select the required fields from the table + $query->select('c.*') + ->from(_JOOM_TABLE_COMMENTS.' AS c'); + + // Join over the images + $query->select('i.id, i.imgtitle, i.imgthumbname, i.catid, i.owner') + ->join('LEFT', _JOOM_TABLE_IMAGES.' AS i ON i.id = c.cmtpic'); + + $query->where('c.published = 1'); + $query->where('c.approved = '.($approved ? '1' : '0')); + + $query->order($orderby); + + return $this->_getList($query, 0, $limit); + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @return void + * @since 3.0 + */ + protected function populateState() + { + $this->setState('message', $this->_mainframe->getUserState('joom.control.message')); + $this->setState('extension_message', $this->_mainframe->getUserState('joom.control.extension_message')); + $this->_mainframe->setUserState('joom.control.message', null); + $this->_mainframe->setUserState('joom.control.extension_message', null); + + parent::populateState(); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/models/cssedit.php b/deployed/joomgallery/administrator/components/com_joomgallery/models/cssedit.php new file mode 100644 index 00000000..1eee9464 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/models/cssedit.php @@ -0,0 +1,25 @@ +_db->getQuery(true) + ->select('a.*, c.cid AS category_id, c.name AS category_name, g.title AS groupname') + ->from(_JOOM_TABLE_IMAGES.' AS a') + ->leftJoin(_JOOM_TABLE_CATEGORIES.' AS c ON c.cid = a.id') + ->leftJoin('#__viewlevels AS g ON g.id = a.access') + ->where('a.id IN ('.implode(',', $cid).')'); + + return $query; + } + + /** + * Retrieves the data of the selected images + * + * @return array Array of objects containing the images data from the database + * @since 1.5.5 + */ + public function getImages() + { + // Lets load the data if it doesn't already exist + if(empty($this->_images)) + { + $query = $this->_buildQuery(); + $this->_images = $this->_getList($query); + } + + return $this->_images; + } + + /** + * Method to get the 'editimages' form + * + * @return mixed A JForm object on success, false on failure + * @since 2.0 + */ + public function getForm() + { + JForm::addFormPath(JPATH_COMPONENT.'/models/forms'); + JForm::addFieldPath(JPATH_COMPONENT.'/models/fields'); + JForm::addRulePath(JPATH_COMPONENT.'/models/rules'); + + $form = JForm::getInstance(_JOOM_OPTION.'.editimages', 'editimages'); + if(empty($form)) + { + return false; + } + + return $form; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/models/favourites.php b/deployed/joomgallery/administrator/components/com_joomgallery/models/favourites.php new file mode 100644 index 00000000..2d25408a --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/models/favourites.php @@ -0,0 +1,108 @@ +_db->getQuery(true) + ->delete(_JOOM_TABLE_USERS); + $this->_db->setQuery($query); + + if(!$this->_db->query()) + { + $this->setError($this->_db->getErrorMsg()); + + return false; + } + + // Delete all created zips in component directory + if(!$this->deleteArchives()) + { + return false; + } + + return true; + } + + /** + * Synchronizes the entries in the users table of JoomGallery + * with users registered and deletes all zips of favourites. + * + * @return boolean True on success, false otherwise + * @since 2.0 + */ + public function synchronize() + { + // Synchronize users-users + $subquery = $this->_db->getQuery(true) + ->select('id') + ->from('#__users AS ju') + ->where('ju.id = uuserid'); + $query = $this->_db->getQuery(true) + ->delete(_JOOM_TABLE_USERS) + ->where('NOT EXISTS ('.$subquery.')'); + $this->_db->setQuery($query); + + if(!$this->_db->query()) + { + $this->setError($this->_db->getErrorMsg()); + + return false; + } + + // Delete all created zips in component directory + if(!$this->deleteArchives()) + { + return false; + } + + return true; + } + + /** + * Deletes all created zips of favourites + * + * @return boolean True on success, false otherwise + * @since 2.0 + */ + protected function deleteArchives() + { + jimport('joomla.filesystem.file'); + + $archives = JFolder::files(JPATH_COMPONENT_SITE, '.zip', false, true); + if(!JFile::delete($archives)) + { + $this->setError(JText::_('COM_JOOMGALLERY_MAIMAN_FV_ERROR_DELETING_ARCHIVES')); + + return false; + } + + return true; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/cbaccesslevel.php b/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/cbaccesslevel.php new file mode 100644 index 00000000..bc08bff0 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/cbaccesslevel.php @@ -0,0 +1,56 @@ +element['cbname'] ? $this->element['cbname'] : 'change[]'; + $cbvalue = $this->element['cbvalue'] ? $this->element['cbvalue'] : $this->name; + $cbid = str_replace(array('[', ']'), array('', ''), $cbname.$cbvalue); + $cbhtml = ''; + $label = parent::getLabel(); + $insertpos = strpos($label, '>'); + $label = substr_replace($label, $cbhtml, $insertpos + 1, 0); + + return $label; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/cbcategory.php b/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/cbcategory.php new file mode 100644 index 00000000..fa090e2b --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/cbcategory.php @@ -0,0 +1,71 @@ +element['cbname'] ? $this->element['cbname'] : 'change[]'; + $cbvalue = $this->element['cbvalue'] ? $this->element['cbvalue'] : $this->name; + $validate = $this->element['validate'] ? (string) $this->element['validate'] : ''; + $cbid = str_replace(array('[', ']'), array('', ''), $cbname.$cbvalue); + + $cbonclick = ''; + if(!empty($validate)) + { + $cbonclick = "if(jQuery('#".$cbid."').prop('checked')) { var el = jQuery('#".$this->id."'); el.addClass('validate-".$validate."'); el.attr('aria-required', 'true').attr('required', 'required'); } else { var el = jQuery('#".$this->id."'); el.removeClass('validate-".$validate."'); el.removeAttr('aria-required').removeAttr('required');}"; + + $js = " + jQuery(document).ready(function() { + ".$cbonclick." + });"; + $doc = JFactory::getDocument(); + $doc->addScriptDeclaration($js); + } + $cbhtml = ''; + + $label = parent::getLabel(); + $insertpos = strpos($label, '>'); + $label = substr_replace($label, $cbhtml, $insertpos + 1, 0); + + return $label; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/cbeditor.php b/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/cbeditor.php new file mode 100644 index 00000000..3ae40e89 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/cbeditor.php @@ -0,0 +1,57 @@ +element['cbname'] ? $this->element['cbname'] : 'change[]'; + $cbvalue = $this->element['cbvalue'] ? $this->element['cbvalue'] : $this->name; + + $cbid = str_replace(array('[', ']'), array('', ''), $cbname.$cbvalue); + $cbhtml = ''; + $label = parent::getLabel(); + $insertpos = strpos($label, '>'); + $label = substr_replace($label, $cbhtml, $insertpos + 1, 0); + + return $label; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/cbjoomuser.php b/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/cbjoomuser.php new file mode 100644 index 00000000..d3189b70 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/cbjoomuser.php @@ -0,0 +1,55 @@ +element['cbname'] ? $this->element['cbname'] : 'change[]'; + $cbvalue = $this->element['cbvalue'] ? $this->element['cbvalue'] : $this->name; + + $cbid = str_replace(array('[', ']'), array('', ''), $cbname.$cbvalue); + $cbhtml = ''; + $label = $cbhtml . parent::getLabel(); + + return $label; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/cblist.php b/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/cblist.php new file mode 100644 index 00000000..8a813d43 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/cblist.php @@ -0,0 +1,57 @@ +element['cbname'] ? $this->element['cbname'] : 'change[]'; + $cbvalue = $this->element['cbvalue'] ? $this->element['cbvalue'] : $this->name; + + $cbid = str_replace(array('[', ']'), array('', ''), $cbname.$cbvalue); + $cbhtml = ''; + $label = parent::getLabel(); + $insertpos = strpos($label, '>'); + $label = substr_replace($label, $cbhtml, $insertpos + 1, 0); + + return $label; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/cbtext.php b/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/cbtext.php new file mode 100644 index 00000000..2657400c --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/cbtext.php @@ -0,0 +1,62 @@ +element['cbname'] ? $this->element['cbname'] : 'change[]'; + $cbvalue = $this->element['cbvalue'] ? $this->element['cbvalue'] : $this->name; + $cbrequired = $this->element['cbrequired'] ? (string) $this->element['cbrequired'] : 'false'; + $cbid = str_replace(array('[', ']'), array('', ''), $cbname.$cbvalue); + + $cbonclick = ''; + if($cbrequired == 'true' || $cbrequired == 'required' || $cbrequired == '1') + { + $cbonclick = "javascript: var el = jQuery('#".$this->id."'); if(jQuery('#".$cbid."').prop('checked')) { el.attr('aria-required', 'true').attr('required', 'required');} else {el.removeAttr('aria-required').removeAttr('required');}"; + } + $cbhtml = ''; + + $label = $cbhtml . parent::getLabel(); + + return $label; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/cbtextarea.php b/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/cbtextarea.php new file mode 100644 index 00000000..242a18a5 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/cbtextarea.php @@ -0,0 +1,62 @@ +element['cbname'] ? $this->element['cbname'] : 'change[]'; + $cbvalue = $this->element['cbvalue'] ? $this->element['cbvalue'] : $this->name; + $cbrequired = $this->element['cbrequired'] ? (string) $this->element['cbrequired'] : 'false'; + $cbid = str_replace(array('[', ']'), array('', ''), $cbname.$cbvalue); + + $cbonclick = ''; + if($cbrequired == 'true' || $cbrequired == 'required' || $cbrequired == '1') + { + $cbonclick = "javascript: var el = jQuery('#".$this->id."'); if(jQuery('#".$cbid."').prop('checked')) { el.attr('aria-required', 'true').attr('required', 'required');} else {el.removeAttr('aria-required').removeAttr('required');}"; + } + $cbhtml = ''; + + $label = $cbhtml . parent::getLabel(); + + return $label; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/files.php b/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/files.php new file mode 100644 index 00000000..52bc22b7 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/files.php @@ -0,0 +1,62 @@ +element['quantity']) ? (int) $this->element['quantity'] : 10; + + // Initialize some field attributes + $accept = $this->element['accept'] ? ' accept="'.(string) $this->element['accept'].'"' : ''; + $size = $this->element['size'] ? ' size="'.(int) $this->element['size'].'"' : ''; + $class = $this->element['class'] ? ' class="'.trim(str_replace('required', '', (string) $this->element['class'])).'"' : ''; + $fsclass = $this->element['fieldsetclass'] ? ' '.(string) $this->element['fieldsetclass'] : ''; + $disabled = ((string) $this->element['disabled'] == 'true') ? ' disabled="disabled"' : ''; + $onchange = $this->element['onchange'] ? ' onchange="'.(string) $this->element['onchange'].'"' : ''; + + $fields = array(); + for($i = 0; $i < $count; $i++) + { + $name = $this->name.'['.$i.']'; + $id = $this->id.$i; + $fields[] = ''; + } + + return '

    '.implode('', $fields).'
    '; + } +} diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/fineuploader.php b/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/fineuploader.php new file mode 100644 index 00000000..119e1f9a --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/fineuploader.php @@ -0,0 +1,382 @@ +isSite()) + { + $url = JRoute::_('index.php?option='._JOOM_OPTION.'&task=ajaxupload.upload', false); + } + + $fileSizeLimit = $app->isSite() ? $config->get('jg_maxfilesize') : 0; + $chunkSize = 0; + $post_max_size = @ini_get('post_max_size'); + if(!empty($post_max_size)) + { + $post_max_size = JoomHelper::iniToBytes($post_max_size); + $chunkSize = (int) min(500000, (int)(0.8 * $post_max_size)); + } + $upload_max_filesize = @ini_get('upload_max_filesize'); + if(!empty($upload_max_filesize)) + { + $upload_max_filesize = JoomHelper::iniToBytes($upload_max_filesize); + + if($fileSizeLimit <= 0 || $fileSizeLimit > $upload_max_filesize) + { + $fileSizeLimit = $upload_max_filesize; + } + } + + $editFilename = $app->isSite() ? $config->get('jg_useruseorigfilename') : $config->get('jg_useorigfilename'); + $prefix = $this->element['field_id_prefix']; + $isMini = $this->element['mini'] && $this->element['mini'] != 'false'; + $redirect = $this->element['redirect']; + $insertOptions = $this->element['insert_options'] && $this->element['insert_options'] != 'false'; + $formId = $this->element['form_id']; + $catidField = $this->element['catid_field'] ? $this->element['catid_field'] : 'catid'; + + if(!$formId) + { + throw new RuntimeException('Attribute \'form_id\' is required for the fineuploader field.'); + } + + ob_start(); ?> +
    + + +element['directory']; + if(!is_dir($directory)) + { + $directory = JPATH_ROOT.'/'.$directory; + } + $files = JFolder::files($directory, '\.bmp$|\.gif$|\.jpg$|\.png$|\.jpeg$|\.jpe$|\.BMP$|\.GIF$|\.JPG$|\.PNG$|\.JPEG$|\.JPE$'); + if(!$files) + { + $files = array(); + } + + // Create attributes + $class = $this->element['class'] ? (string) $this->element['class'] : ''; + if($this->element['required'] && $this->element['required'] == true && strpos($class, 'required') === false) + { + if(!empty($class)) + { + $class .= ' '; + } + $class .= 'required'; + } + $attr = !empty($class) ? ' class="'.$class.'"' : ''; + $attr .= $this->element['size'] ? ' size="' . (int) $this->element['size'] . '"' : ''; + $attr .= $this->multiple ? ' multiple="multiple"' : ''; + $attr .= $this->element['onchange'] ? ' onchange="' . (string) $this->element['onchange'] . '"' : ''; + + // To avoid user's confusion, readonly="true" should imply disabled="true". + if ((string) $this->element['readonly'] == 'true' || (string) $this->element['disabled'] == 'true') + { + $attr .= ' disabled="disabled"'; + } + + // Create HTML + $html = ' +

    + + +

    '; + + return $html; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/ftpfolders.php b/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/ftpfolders.php new file mode 100644 index 00000000..538bea04 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/ftpfolders.php @@ -0,0 +1,102 @@ +element['directory']; + if(!is_dir($directory)) + { + $directory = JPath::clean(JPATH_ROOT.'/'.$directory); + } + $folders = JFolder::folders($directory, '.', true, true); + + if(!$folders || !count($folders)) + { + return ''; + } + + // Create attributes + $class = $this->element['class'] ? (string) $this->element['class'] : ''; + if($this->element['required'] && $this->element['required'] == true && strpos($class, 'required') === false) + { + if(!empty($class)) + { + $class .= ' '; + } + $class .= 'required'; + } + $attr = !empty($class) ? ' class="'.$class.'"' : ''; + $attr .= $this->element['size'] ? ' size="' . (int) $this->element['size'] . '"' : ''; + $attr .= $this->multiple ? ' multiple="multiple"' : ''; + + if(!$this->element['onchange']) + { + $attr .= ' onchange="document.adminForm.task.value=\'\';document.adminForm.submit();"'; + } + else + { + $attr .= ' onchange="' . (string) $this->element['onchange'] . '"'; + } + + // To avoid user's confusion, readonly="true" should imply disabled="true". + if ((string) $this->element['readonly'] == 'true' || (string) $this->element['disabled'] == 'true') + { + $attr .= ' disabled="disabled"'; + } + + // Create HTML + $html = ''; + + return $html; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/image.php b/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/image.php new file mode 100644 index 00000000..adef1914 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/image.php @@ -0,0 +1,129 @@ +required ? ' required="required"' : ''; + $validate = ($this->validate && $this->validate == 'joompositivenumeric') ? true : false; + $class = ''; + $script = array(); + $html = array(); + $css = array(); + + JHtml::_('bootstrap.tooltip'); + + if($validate) + { + $class = 'validate-' . $this->validate; + + // Add a validation script for form validation + $script[] = ' jQuery(document).ready(function() {'; + $script[] = ' document.formvalidator.setHandler("joompositivenumeric", function(value) {'; + $script[] = ' regex = /^[1-9]+[0-9]*$/;'; + $script[] = ' return regex.test(value);'; + $script[] = ' })'; + $script[] = ' });'; + } + + // Add script for fetching the selected image in the modal dialog + $script[] = ' function joom_selectimage(id, title, object) {'; + $script[] = ' document.getElementById(object).value = id;'; + $script[] = ' document.getElementById(object + "_name").value = title;'; + $script[] = ' jQuery("#modalSelectImage").modal("hide");'; + if($validate) + { + $script[] = ' document.formvalidator.validate(document.getElementById(object));'; + $script[] = ' document.formvalidator.validate(document.getElementById(object + "_name"));'; + } + $script[] = ' }'; + + $doc->addScriptDeclaration(implode("\n", $script)); + + $doc->addStyleDeclaration(implode("\n", $css)); + + JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_joomgallery/tables'); + $img = JTable::getInstance('joomgalleryimages', 'Table'); + + if($this->value) + { + $img->load($this->value); + } + else + { + $img->imgtitle = ''; + } + + $link = 'index.php?option=com_joomgallery&view=mini&extended=0&format=raw&catid=0&object=' . $this->id; + $title = htmlspecialchars($img->imgtitle, ENT_QUOTES, 'UTF-8'); + + $html[] = ''; + $html[] = ''; + $html[] = '' + . ' ' . JText::_('JSELECT') + . ''; + + $html[] = ''; + + if($this->required) + { + if(!empty($class)) + { + $class .= ' '; + } + $class .= 'required'; + } + + $html[] = ''; + + $html[] = JHtmlBootstrap::renderModal( + 'modalSelectImage', array( + 'url' => $link . '&' . JSession::getFormToken() . '=1"', + 'title' => JText::_('COM_JOOMGALLERY_LAYOUT_COMMON_CHOOSE_IMAGE'), + 'width' => '620px', + 'height' => '390px', + 'footer' => '' + ) + ); + + return implode("\n", $html); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/imagepreview.php b/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/imagepreview.php new file mode 100644 index 00000000..e3bb9fda --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/imagepreview.php @@ -0,0 +1,46 @@ +element['class'] ? (string) $this->element['class'] : ''; + $class = 'class="jg_imgpreview'.(!empty($class) ? ' '.$class : '').'"'; + + return ''.JText::_('COM_JOOMGALLERY_IMGMAN_IMAGE_PREVIEW').''; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/joomcategory.php b/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/joomcategory.php new file mode 100644 index 00000000..add665b3 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/joomcategory.php @@ -0,0 +1,98 @@ +element['class'] ? (string) $this->element['class'] : ''; + if($this->element['required'] && $this->element['required'] == true && strpos($class, 'required') === false) + { + if(!empty($class)) + { + $class .= ' '; + } + $class .= 'required'; + } + if($this->element['validate'] && (string) $this->element['validate'] == 'joompositivenumeric') + { + $doc = JFactory::getDocument(); + + // Add a validation script for form validation + $js_validate = " + jQuery(document).ready(function() { + document.formvalidator.setHandler('joompositivenumeric', function(value) { + regex=/^[1-9]+[0-9]*$/; + return regex.test(value); + }) + });"; + $doc->addScriptDeclaration($js_validate); + // Element class needs attribute validate-... + if(!empty($class)) + { + $class .= ' '; + } + $class .= 'validate-'.(string) $this->element['validate']; + + // Add some style to make the slect box red bordered when invalid + $css = ' + select.invalid { + border: 1px solid red; + }'; + $doc->addStyleDeclaration($css); + } + + $attr = ''; + $attr .= !empty($class) ? ' class="'.$class.'"' : ''; + $attr .= ((string) $this->element['disabled'] == 'true') ? ' disabled="disabled"' : ''; + $attr .= $this->element['size'] ? ' size="'.(int) $this->element['size'].'"' : ''; + $attr .= $this->element['onchange'] ? ' onchange="'.(string) $this->element['onchange'].'"' : ''; + $action = $this->element['action'] ? (string) $this->element['action'] : 'core.create'; + $exclude = $this->element['exclude'] ? (int) $this->element['exclude'] : null; + $task = $this->element['task'] ? (int) $this->element['task'] : null; + + $html = JHTML::_('joomselect.categorylist', $this->value, $this->name, $attr, $exclude, '- ', $task, $action, $this->id); + + return $html; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/joomdatabase.php b/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/joomdatabase.php new file mode 100644 index 00000000..13869684 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/joomdatabase.php @@ -0,0 +1,118 @@ +element['label']) + { + $this->element['label'] = 'COM_JOOMGALLERY_MIGMAN_FIELD_JOOMDATABASE_LABEL'; + } + + if(!$this->description) + { + $this->description = 'COM_JOOMGALLERY_MIGMAN_FIELD_JOOMDATABASE_DESC'; + } + + return parent::getLabel(); + } + + /** + * Method to get the field input markup. + * Adds the remaining fields for the database connection to the form + * + * @return string The field input markup + * @since 3.1 + */ + protected function getInput() + { + $numberOfFields = 6; + + $this->form->loadFile('database'); + + // Remove field 'prefix' is required + $prefix = (string) $this->element['prefix']; + if($prefix == 'false' || $prefix == '0') + { + $this->form->removeField('prefix', 'db'); + + $numberOfFields--; + } + + // If second database connection is required remove + // checkbox and change 'required' field attributes + if($this->required) + { + $this->form->removeField('database'); + $this->form->setFieldAttribute('db_type', 'required', 'true', 'db'); + $this->form->setFieldAttribute('db_host', 'required', 'true', 'db'); + $this->form->setFieldAttribute('db_user', 'required', 'true', 'db'); + $this->form->setFieldAttribute('db_name', 'required', 'true', 'db'); + $this->form->setFieldAttribute('prefix', 'required', 'true', 'db'); + } + + // Create individual IDs for each of the fields + $id = str_replace('database_', '', $this->id); + $this->form->setFieldAttribute('enabled', 'id', 'enabled_'.$id, 'db'); + $this->form->setFieldAttribute('db_type', 'id', 'db_type_'.$id, 'db'); + $this->form->setFieldAttribute('db_host', 'id', 'db_host_'.$id, 'db'); + $this->form->setFieldAttribute('db_user', 'id', 'db_user_'.$id, 'db'); + $this->form->setFieldAttribute('db_pass', 'id', 'db_pass_'.$id, 'db'); + $this->form->setFieldAttribute('db_name', 'id', 'db_name_'.$id, 'db'); + $this->form->setFieldAttribute('prefix', 'id', 'prefix_'.$id, 'db'); + + $script = 'var group = jQuery(\'#'.$this->id.'\').parent().parent();'; + $script .= 'for(var i = 0; i < '.$numberOfFields.'; i++){group = group.next();group.toggleClass(\'hide\');}'; + + if(!$this->value && !isset($this->form->joomScriptLoaded)) + { + JFactory::getDocument()->addScriptDeclaration('jQuery(document).ready(function(){ + if(!jQuery(\'#'.$this->id.'\').prop(\'checked\')){jQuery(\'#db_enabled_'.$id.'\').val(\'0\'); + '.$script.'}else{jQuery(\'#db_enabled_'.$id.'\').val(\'1\');}});'); + + $this->form->joomScriptLoaded = true; + } + + $this->element['onclick'] = $script.'jQuery(\'#db_enabled_'.$id.'\').val(1 - jQuery(\'#db_enabled_'.$id.'\').val());'; + + return parent::getInput(); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/joomlist.php b/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/joomlist.php new file mode 100644 index 00000000..4f49bafe --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/models/fields/joomlist.php @@ -0,0 +1,99 @@ +element->children() as $option) + { + // Only add
    +

    +
    +

    migration).'_MIGRATIONCHECK'); ?>

    +
    +
    + description): ?> +
    description; ?>
    + fields as $field): + if(!$field->hidden): ?> +
    +
    + label; ?> +
    +
    + input; ?> +
    +
    + +
    input; ?>
    + fields)): ?> +
    +
    + +
    + +
    + +
    + + +
    + +
    +
    + + + + + + + + + + + + + + + + items as $key => $item): + $orderkey = array_search($item->cid, $ordering[$item->parent_id]); + $canEdit = $this->_user->authorise('core.edit', _JOOM_OPTION.'.category.'.$item->cid); + $canEditOwn = $this->_user->authorise('core.edit.own', _JOOM_OPTION.'.category.'.$item->cid) && $item->owner == $this->_user->get('id'); + $canChange = $this->_user->authorise('core.edit.state', _JOOM_OPTION.'.category.'.$item->cid); + + // Get the parents of item for sorting + if ($item->level > 1) + { + $parentsStr = ''; + $_currentParentId = $item->parent_id; + $parentsStr = ' '.$_currentParentId; + for($j = 0; $j < $item->level; $j++) + { + foreach($ordering as $k => $v) + { + $v = implode('-', $v); + $v = '-'.$v.'-'; + if(strpos($v, '-'.$_currentParentId.'-') !== false) + { + $parentsStr .= ' '.$k; + $_currentParentId = $k; + break; + } + } + } + } + else + { + $parentsStr = ''; + } + ?> + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + +
    + + + + + + + + + cid); ?> + + cid) : null, true); ?> + + published, $i, '', $canChange); + if($item->published && $item->hidden): + echo ''.JText::_('COM_JOOMGALLERY_COMMON_HIDDEN_ASTERISK').''; + $display_hidden_asterisk = true; + endif; ?> + + |—', $item->level - 1); ?> + + + escape($item->name); ?> + + escape($item->name); ?> + + + escape($item->alias)); ?> + + + cid, false); ?> + + escape($item->access_level); ?> + + owner); ?> + + + + + cid; ?> +
    +
    + pagination->getListFooter(); ?> + +
    + +
    + + + loadTemplate('batch'); ?> + + + + + +
    + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/categories/tmpl/default_batch.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/categories/tmpl/default_batch.php new file mode 100644 index 00000000..6916082d --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/categories/tmpl/default_batch.php @@ -0,0 +1,51 @@ +state->get('filter.published'); +?> + diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/categories/tmpl/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/categories/tmpl/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/categories/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/categories/view.html.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/categories/view.html.php new file mode 100644 index 00000000..cede424b --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/categories/view.html.php @@ -0,0 +1,93 @@ +items = $this->get('Categories'); + $this->state = $this->get('State'); + $this->pagination = $this->get('Pagination'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + $this->addToolbar(); + + $this->sidebar = JHtmlSidebar::render(); + + parent::display($tpl); + } + + /** + * Add the toolbar and toolbar title. + * + * @access protected + * @return void + * + * @since 2.0 + */ + protected function addToolbar() + { + // Get the results for each action + $canDo = JoomHelper::getActions(); + + JToolBarHelper::title(JText::_('COM_JOOMGALLERY_CATMAN_CATEGORY_MANAGER'), 'folder'); + + if($this->_config->get('jg_disableunrequiredchecks') || $canDo->get('core.create') || count(JoomHelper::getAuthorisedCategories('core.create'))) + { + JToolbarHelper::addNew('new'); + } + + if(($this->_config->get('jg_disableunrequiredchecks') || $canDo->get('core.edit') || count(JoomHelper::getAuthorisedCategories('core.edit'))) && $this->pagination->total) + { + JToolbarHelper::editList('edit'); + JHtml::_('bootstrap.modal', 'collapseModal'); + $title = JText::_('JTOOLBAR_BATCH'); + $dhtml = ""; + JToolBar::getInstance('toolbar')->appendButton('Custom', $dhtml, 'batch'); + JToolbarHelper::divider(); + } + + if(($this->_config->get('jg_disableunrequiredchecks') || count(JoomHelper::getAuthorisedCategories('core.edit.state'))) && $this->pagination->total) + { + JToolbarHelper::publishList('publish', 'COM_JOOMGALLERY_COMMON_PUBLISH'); + JToolbarHelper::unpublishList('unpublish', 'COM_JOOMGALLERY_COMMON_UNPUBLISH'); + JToolbarHelper::divider(); + } + + if(($this->_config->get('jg_disableunrequiredchecks') || $canDo->get('core.delete') || count(JoomHelper::getAuthorisedCategories('core.delete'))) && $this->pagination->total) + { + JToolbarHelper::deleteList('','remove'); + JToolbarHelper::divider(); + } + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/category/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/category/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/category/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/category/tmpl/form.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/category/tmpl/form.php new file mode 100644 index 00000000..42ae2340 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/category/tmpl/form.php @@ -0,0 +1,233 @@ + + +
    +
    + +
    +
    +
    +
    +
    +
    + form->getLabel('name'); ?> +
    +
    + form->getInput('name'); ?> +
    +
    +
    +
    + form->getLabel('alias'); ?> +
    +
    + form->getInput('alias'); ?> +
    +
    +
    +
    +
    +
    + form->getLabel('publishhiddenstate'); ?> +
    +
    + form->getInput('publishhiddenstate'); ?> +
    +
    +
    +
    +
    +
    +
    +
    + form->getLabel('description'); ?> +
    +
    + form->getInput('description'); ?> +
    +
    +
    +
    +
    +

    +
    +
    +
    +
    +
    +
    + form->getLabel('parent_id'); ?> +
    +
    + form->getInput('parent_id'); ?> +
    +
    +
    +
    + form->getLabel('published'); ?> +
    +
    + form->getInput('published'); ?> +
    +
    +
    +
    + form->getLabel('hidden'); ?> +
    +
    + form->getInput('hidden'); ?> +
    +
    +
    +
    + form->getLabel('access'); ?> +
    +
    + form->getInput('access'); ?> +
    +
    +
    +
    + form->getLabel('exclude_toplists'); ?> +
    +
    + form->getInput('exclude_toplists'); ?> +
    +
    +
    +
    + form->getLabel('exclude_search'); ?> +
    +
    + form->getInput('exclude_search'); ?> +
    +
    +
    +
    + form->getLabel('cid'); ?> +
    +
    + form->getInput('cid'); ?> +
    +
    +form->getValue('notice')): ?> +
    +
    + form->getLabel('notice'); ?> +
    +
    + form->getValue('notice'); ?> +
    +
    + +
    +
    +
    +
    + form->getLabel('owner'); ?> +
    +
    + form->getInput('owner'); ?> +
    +
    +
    +
    + form->getLabel('imagelib'); ?> +
    +
    + form->getInput('imagelib'); ?> +
    +
    +
    +
    + form->getLabel('thumbnail'); ?> +
    +
    + form->getInput('thumbnail'); ?> +
    +
    +
    +
    + form->getLabel('img_position'); ?> +
    +
    + form->getInput('img_position'); ?> +
    +
    + _config->get('jg_disableunrequiredchecks')): ?> +
    +
    + form->getLabel('ordering'); ?> +
    +
    + form->getInput('ordering'); ?> +
    +
    + +
    +
    + form->getLabel('password'); ?> +
    +
    + form->getInput('password'); ?> +
    +
    +
    +
    +
    +
    + loadTemplate('options'); ?> +
    +
    + loadTemplate('metadata'); ?> +
    + _user->authorise('core.admin', _JOOM_OPTION.'.category.'.$this->item->cid)): ?> +
    + form->getInput('rules'); ?> +
    + +
    +
    + + + +
    + +
    +
    + form->getLabel('metadesc'); ?> +
    +
    + form->getInput('metadesc'); ?> +
    +
    +
    +
    + form->getLabel('metakey'); ?> +
    +
    + form->getInput('metakey'); ?> +
    +
    +form->getGroup('metadata') as $field): ?> +
    + hidden): ?> +
    + input; ?> +
    + +
    + label; ?> +
    +
    + input; ?> +
    + +
    + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/category/tmpl/form_options.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/category/tmpl/form_options.php new file mode 100644 index 00000000..b9df4317 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/category/tmpl/form_options.php @@ -0,0 +1,26 @@ + 'collapse0')); +$fieldSets = $this->form->getFieldsets(); +$i = 0; + +foreach($fieldSets as $name => $fieldSet): + if($name != ''): + echo JHtml::_('bootstrap.addSlide', 'categoryOptions', JText::_($fieldSet->label), 'collapse'.$i++); + if(isset($fieldSet->description) && trim($fieldSet->description)): + echo '

    '.$this->escape(JText::_($fieldSet->description)).'

    '; + endif; + ?> + form->getFieldset($name) as $field): ?> +
    +
    + label; ?> +
    +
    + input; ?> +
    +
    + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/category/view.html.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/category/view.html.php new file mode 100644 index 00000000..3417ec36 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/category/view.html.php @@ -0,0 +1,201 @@ +get('Data'); + + $isNew = ($item->cid < 1); + if($isNew) + { + $item->published = 1; + } + + // Get image source for the thumbnail preview + if($item->thumbnail && $item->thumbnail_available) + { + $imgsource = $this->_ambit->getImg('thumb_url', $item->thumbnail); + } + else + { + $imgsource = '../media/system/images/blank.png'; + } + + // Get the form and fill the fields + $form = $this->get('Form'); + if(!$isNew) + { + // Add additional attribute for category form field to exclude current + // category id from select box + $form->setFieldAttribute('parent_id', 'exclude', $item->cid); + } + + // Ordering box is not available if option for performance improvement has been enabled + if(!$this->_config->get('jg_disableunrequiredchecks')) + { + // Set some additional attributes for the ordering select box + $form->setFieldAttribute('ordering', 'originalOrder', $item->cid); + $form->setFieldAttribute('ordering', 'originalParent', $item->parent_id == 1 ? 0 : $item->parent_id); + $form->setFieldAttribute('ordering', 'orderings', base64_encode(serialize($this->getModel()->getOrderings($item->cid ? $item->parent_id : null)))); + // Perhaps there is a better way to set the field attribute + $parent_field = $this->_findFieldByFieldName($form, 'parent_id'); + if($parent_field !== false) + { + $form->setFieldAttribute('ordering', 'parent_id', $parent_field->id); + } + } + + $imagelib_field = $this->_findFieldByFieldName($form, 'imagelib'); + // Set additional attribute for the thumbnail select box + if($imagelib_field !== false) + { + $form->setFieldAttribute('thumbnail', 'imagelib_id', $imagelib_field->id); + } + + // Set maximum allowed user count to switch from listbox to modal popup selection + $form->setFieldAttribute('owner', 'useListboxMaxUserCount', $this->_config->get('jg_use_listbox_max_user_count')); + + // Bind the data to the form + $form->bind($item); + + // Set thumbnail image source for thumbnail preview form field + $form->setValue('imagelib', null, $imgsource); + + // Set immutable fields + if($item->published) + { + $form->setValue('publishhiddenstate', null, $item->hidden ? JText::_('COM_JOOMGALLERY_COMMON_PUBLISHED_BUT_HIDDEN') : JText::_('COM_JOOMGALLERY_COMMON_STATE_PUBLISHED') ); + } + else + { + $form->setValue('publishhiddenstate', null, JText::_('COM_JOOMGALLERY_COMMON_STATE_UNPUBLISHED')); + } + + if($item->thumbnail && !$item->thumbnail_available) + { + $form->setValue('notice', null, JText::sprintf('COM_JOOMGALLERY_CATMAN_THUMBNAIL_NOT_AVAILABLE', $item->thumbnail)); + } + + JHtml::_('jquery.framework'); + + $this->assignRef('item', $item); + $this->assignRef('isNew', $isNew); + $this->assignRef('form', $form); + + $this->addToolbar(); + parent::display($tpl); + } + + /** + * Find a form field by field name + * + * @access private + * @param object $form The form object to search in + * @param string $fieldname The field name to search + * @return mixed The form field object or false, if field could not be found + * @since 2.0 + */ + private function _findFieldByFieldName($form, $fieldname) + { + foreach($form->getFieldset() As $field) + { + if($field->fieldname == $fieldname) + { + return $field; + } + } + + return false; + } + + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 2.0 + */ + public function addToolbar() + { + // Get the results for each action + $canDo = JoomHelper::getActions('category', $this->item->cid); + + $title = JText::_('COM_JOOMGALLERY_CATMAN_CATEGORY_MANAGER').' :: '; + if($this->isNew) + { + $title .= JText::_('COM_JOOMGALLERY_CATMAN_ADD_CATEGORY'); + } + else + { + $title .= JText::_('COM_JOOMGALLERY_CATMAN_EDIT_CATEGORY'); + } + $title .= ' ' .JText::_('COM_JOOMGALLERY_COMMON_CATEGORY'); + + JToolBarHelper::title($title, 'folder'); + + // For new categories check the create permission + if($this->isNew && ($this->_config->get('jg_disableunrequiredchecks') || $canDo->get('core.create') || count(JoomHelper::getAuthorisedCategories('core.create')))) + { + JToolBarHelper::apply('apply', 'JTOOLBAR_APPLY'); + JToolBarHelper::save('save', 'JTOOLBAR_SAVE'); + JToolBarHelper::custom('save2new', 'save-new.png', 'save-new_f2.png', 'JTOOLBAR_SAVE_AND_NEW', false); + } + else + { + if(($canDo->get('core.edit') || ($canDo->get('core.edit.own') && $this->item->owner == $this->_user->get('id')))) + { + JToolBarHelper::apply('apply', 'JTOOLBAR_APPLY'); + JToolBarHelper::save('save', 'JTOOLBAR_SAVE'); + if($this->_config->get('jg_disableunrequiredchecks') || $canDo->get('core.create') || count(JoomHelper::getAuthorisedCategories('core.create'))) + { + JToolBarHelper::save2new(); + } + } + } + + // If it's an already existing category a copy may be saved (only if creating categories is allowed) + if(!$this->isNew && ($this->_config->get('jg_disableunrequiredchecks') || $canDo->get('core.create') || count(JoomHelper::getAuthorisedCategories('core.create')))) + { + JToolBarHelper::save2copy(); + } + + if($this->isNew) + { + JToolBarHelper::cancel('cancel','JTOOLBAR_CANCEL'); + } + else + { + JToolBarHelper::cancel('cancel', 'JTOOLBAR_CLOSE'); + } + JToolbarHelper::spacer(); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/changelog/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/changelog/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/changelog/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/changelog/tmpl/default.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/changelog/tmpl/default.php new file mode 100644 index 00000000..327b348b --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/changelog/tmpl/default.php @@ -0,0 +1,60 @@ +changelog->release as $release): ?> +

    attributes()->version?> published attributes()->published, JText::_('DATE_FORMAT_LC4')); ?>

    +entries as $entry): ?> + + + + + + + +logentry as $logentry): + switch($logentry->attributes()->type): + case '*': + $term = 'Security'; + $labelclass = 'label-important'; + break; + case '#': + $term = 'BugFix'; + $labelclass = 'label-warning'; + break; + case '+': + $term = 'New'; + $labelclass = 'label-success'; + break; + case '-': + $term = 'Removed'; + $labelclass = 'label-inverse'; + break; + case '^': + $term = 'Change'; + $labelclass = 'label-info'; + break; + case '!': + default: + $term = 'Note'; + $labelclass = ''; + break; + endswitch; +?> + + + + + + +
    + attributes()->date, JText::_('DATE_FORMAT_LC4')); ?> +
    + + + +
    + + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/changelog/tmpl/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/changelog/tmpl/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/changelog/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/changelog/view.html.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/changelog/view.html.php new file mode 100644 index 00000000..3b2588a7 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/changelog/view.html.php @@ -0,0 +1,40 @@ +changelog = simplexml_load_file($xml_file); + + parent::display($tpl); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/comments/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/comments/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/comments/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/comments/tmpl/default.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/comments/tmpl/default.php new file mode 100644 index 00000000..56e6e669 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/comments/tmpl/default.php @@ -0,0 +1,122 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$columns = 10; +$approved_states = array(1 => array('reject', 'COM_JOOMGALLERY_COMMON_APPROVED', 'COM_JOOMGALLERY_COMMAN_REJECT_COMMENT', 'COM_JOOMGALLERY_COMMON_APPROVED', false, 'publish', 'publish'), + 0 => array('approve', 'COM_JOOMGALLERY_COMMON_REJECTED', 'COM_JOOMGALLERY_COMMAN_APPROVE_COMMENT', 'COM_JOOMGALLERY_COMMON_REJECTED', false, 'unpublish', 'unpublish')); +?> +
    +sidebar)): ?> +
    + sidebar; ?> +
    +
    + +
    + + $this)); + ?> +state->get('filter.inuse') && !$this->get('Total')) : ?> +
    + +
    + + + + + + + + + + + + + + + + + +items as $i => $item): + $canEdit = $this->_user->authorise('core.edit', _JOOM_OPTION.'.image.'.$item->cmtpic); + $canEditOwn = $this->_user->authorise('core.edit.own', _JOOM_OPTION.'.image.'.$item->cmtpic) && $item->owner == $this->_user->get('id'); ?> + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + +
    + cmtid); ?> + + cmtpic : null, true); ?> + + cmtname; ?> + + cmttext; ?> + + published, $i); ?> + + approved, $i); ?> + + + + escape($item->imgtitle); ?> + + + escape($item->imgtitle); ?> + + + cmtip; ?> + + cmtdate, JText::_('DATE_FORMAT_LC4')); ?> + + cmtid; ?> +
    +
    + + pagination->getListFooter(); ?> + + + + +
    + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/comments/tmpl/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/comments/tmpl/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/comments/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/comments/view.html.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/comments/view.html.php new file mode 100644 index 00000000..9c3458a7 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/comments/view.html.php @@ -0,0 +1,64 @@ +items = $this->get('Comments'); + $this->state = $this->get('State'); + $this->pagination = $this->get('Pagination'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + $this->addToolbar(); + + $this->sidebar = JHtmlSidebar::render(); + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 2.0 + */ + public function addToolbar() + { + JToolBarHelper::title(JText::_('COM_JOOMGALLERY_COMMAN_COMMENTS_MANAGER'), 'comments-2'); + JToolbarHelper::publishList('publish', 'COM_JOOMGALLERY_COMMAN_TOOLBAR_PUBLISH_COMMENT'); + JToolbarHelper::unpublishList('unpublish', 'COM_JOOMGALLERY_COMMAN_TOOLBAR_UNPUBLISH_COMMENT'); + JToolbarHelper::custom('approve', 'upload.png', 'upload_f2.png', 'COM_JOOMGALLERY_COMMAN_TOOLBAR_APPROVE_COMMENT'); + JToolbarHelper::divider(); + JToolbarHelper::deleteList('', 'remove', 'COM_JOOMGALLERY_COMMAN_TOOLBAR_REMOVE_COMMENT'); + JToolbarHelper::divider(); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/config/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/config/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/config/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/config/tmpl/default.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/config/tmpl/default.php new file mode 100644 index 00000000..e738ed26 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/config/tmpl/default.php @@ -0,0 +1,973 @@ + +
    +sidebar)): ?> +
    + sidebar; ?> +
    +
    + +
    +_config->isExtended()): + JHtml::_('bootstrap.tooltip'); ?> +
    + + +
    + 1)); +// start first nested MainTab "Grundlegende Einstellungen" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_TAB_GENERAL_SETTINGS'), 'NestedMainPane1'); +// start first nested tabs pane +echo JHtml::_('tabs.start', 'NestedPaneOne', array('useCookie' => 1)); + +// start Tab "Grundlegende Einstellungen->Pfade und Verzeichnisse" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_GS_TAB_PATH_DIRECTORIES'), 'nested-one'); + +JHtml::_('joomconfig.start', 'page1'); + JHtml::_('joomconfig.intro', JText::sprintf('COM_JOOMGALLERY_CONFIG_GS_PD_CSS_CONFIGURATION_INTRO', $this->_config->getStyleSheetName(), $this->cssfilemsg)); + JHtml::_('joomconfig.intro', JText::_('COM_JOOMGALLERY_CONFIG_GS_PD_PATH_DIRECTORIES_INTRO')); +if($this->display): + $field = '
    ['.$this->write_pathimages.']'; + JHtml::_('joomconfig.row', 'jg_pathimages', 'custom', 'COM_JOOMGALLERY_COMMON_IMAGE_PATH', $field, true, '', JText::_('COM_JOOMGALLERY_CONFIG_GS_PD_PATH_IMAGES_STORED')); + $field = '
    ['.$this->write_pathoriginalimages.']'; + JHtml::_('joomconfig.row', 'jg_pathimages', 'custom', 'COM_JOOMGALLERY_CONFIG_GS_PD_ORIGINALS_PATH', $field, true, '', JText::_('COM_JOOMGALLERY_CONFIG_GS_PD_PATH_ORIGINALS_STORED')); + $field = '
    ['.$this->write_paththumbs.']'; + JHtml::_('joomconfig.row', 'jg_pathimages', 'custom', 'COM_JOOMGALLERY_CONFIG_GS_PD_THUMBNAILS_PATH', $field, true, '', JText::_('COM_JOOMGALLERY_CONFIG_GS_PD_PATH_THUMBNAILS_STORED')); +endif; + $field = '
    ['.$this->write_pathftpupload.']'; + JHtml::_('joomconfig.row', 'jg_pathimages', 'custom', 'COM_JOOMGALLERY_CONFIG_GS_PD_FTPUPLOAD_PATH', $field, true, '', JText::_('COM_JOOMGALLERY_CONFIG_GS_PD_PATH_FOR_FTPUPLOAD')); +if($this->display): + $field = '
    ['.$this->write_pathtemp.']'; + JHtml::_('joomconfig.row', 'jg_pathimages', 'custom', 'COM_JOOMGALLERY_CONFIG_GS_PD_TEMP_PATH', $field, true, '', JText::_('COM_JOOMGALLERY_CONFIG_GS_PD_PATH_FOR_TEMP')); +endif; + $field = '
    ['.$this->write_pathwm.']'; + JHtml::_('joomconfig.row', 'jg_pathimages', 'custom', 'COM_JOOMGALLERY_CONFIG_GS_PD_WATERMARK_PATH', $field, true, '', JText::_('COM_JOOMGALLERY_CONFIG_GS_PD_PATH_WATERMARK_STORED')); + $field = '
    ['.$this->wmfilemsg.']'; + JHtml::_('joomconfig.row', 'jg_pathimages', 'custom', 'COM_JOOMGALLERY_CONFIG_GS_PD_WATERMARK_FILE', $field); + JHtml::_('joomconfig.row', 'jg_use_real_paths', 'yesno', 'COM_JOOMGALLERY_CONFIG_GS_PD_USE_REAL_PATHS', $this->_config->jg_use_real_paths); + JHtml::_('joomconfig.row', 'jg_checkupdate', 'yesno', 'COM_JOOMGALLERY_CONFIG_GS_PD_CHECKUPDATE', $this->_config->jg_checkupdate); +JHtml::_('joomconfig.end'); + +if($this->display): +// start Tab "Grundlegende Einstellungen->Ersetzungen" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_GS_TAB_BACKEND_REPLACEMENTS'), 'nested-two'); + +JHTML::_('joomconfig.start', 'page2'); + JHTML::_('joomconfig.intro', JText::_('COM_JOOMGALLERY_CONFIG_GS_RP_BACKEND_REPLACEMENTS_INTRO')); + JHTML::_('joomconfig.row', 'jg_filenamewithjs', 'yesno', 'COM_JOOMGALLERY_CONFIG_GS_RP_FILENAME_WITHJS', $this->_config->jg_filenamewithjs); + $tl_jg_filenamereplace = ''; + JHTML::_('joomconfig.row', 'jg_filenamereplace', 'custom', 'COM_JOOMGALLERY_CONFIG_GS_RP_FILENAME_REPLACE', $tl_jg_filenamereplace); +JHTML::_('joomconfig.end'); + +// start Tab "Grundlegende Einstellungen->Bildmanipulation" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_GS_TAB_IMAGE_PROCESSING'), 'nested-three'); + +JHTML::_('joomconfig.start', 'page3'); + JHTML::_('joomconfig.intro', '
    '.$this->gdmsg.'
    '); + $thumbcreator[] = JHTML::_('select.option','gd1', JText::_('COM_JOOMGALLERY_CONFIG_GS_IP_GDLIB')); + $thumbcreator[] = JHTML::_('select.option','gd2', JText::_('COM_JOOMGALLERY_CONFIG_GS_IP_GD2LIB')); + $thumbcreator[] = JHTML::_('select.option','im', JText::_('COM_JOOMGALLERY_CONFIG_GS_IP_IMAGEMAGICK')); + $mc_jg_thumbcreation = JHTML::_('select.genericlist',$thumbcreator, 'jg_thumbcreation', 'class="inputbox" size="3"', 'value', 'text', $this->_config->jg_thumbcreation); + JHTML::_('joomconfig.row', 'jg_thumbcreation', 'custom', 'COM_JOOMGALLERY_CONFIG_GS_IP_IMAGE_CREATOR', $mc_jg_thumbcreation); + JHTML::_('joomconfig.row', 'jg_fastgd2thumbcreation', 'yesno', 'COM_JOOMGALLERY_CONFIG_GS_IP_FAST_GD2_THUMBCREATION', $this->_config->jg_fastgd2thumbcreation); + $tl_jg_impath = ''; + JHTML::_('joomconfig.row', 'jg_impath', 'custom', 'COM_JOOMGALLERY_CONFIG_GS_IP_PATH_TO_IMAGEMAGICK', $tl_jg_impath, true, '', $this->immsg); + JHTML::_('joomconfig.row', 'jg_resizetomaxwidth', 'yesno', 'COM_JOOMGALLERY_CONFIG_GS_IP_RESIZING', $this->_config->jg_resizetomaxwidth); + JHTML::_('joomconfig.row', 'jg_maxwidth', 'text', 'COM_JOOMGALLERY_CONFIG_GS_IP_MAX_WIDTH', $this->_config->jg_maxwidth); + JHTML::_('joomconfig.row', 'jg_picturequality', 'text', 'COM_JOOMGALLERY_CONFIG_GS_IP_IMAGE_QUALITY', $this->_config->jg_picturequality); + JHTML::_('joomconfig.intro', JText::_('COM_JOOMGALLERY_CONFIG_GS_IP_THUMBNAILS_INTRO')); + $directionresize[] = JHTML::_('select.option','0', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_SAMEHIGHT')); + $directionresize[] = JHTML::_('select.option','1', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_SAMEWIDTH')); + $directionresize[] = JHTML::_('select.option','2', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_FREEHEIGHTWIDTH')); + $mc_jg_useforresizedirection = JHTML::_('select.genericlist',$directionresize, 'jg_useforresizedirection', 'class="inputbox" size="3"', 'value', 'text', $this->_config->jg_useforresizedirection); + JHTML::_('joomconfig.row', 'jg_useforresizedirection', 'custom', 'COM_JOOMGALLERY_CONFIG_GS_IP_DIRECTION_RESIZE', $mc_jg_useforresizedirection); + $cropposition[] = JHTML::_('select.option','0', JText::_('COM_JOOMGALLERY_CONFIG_GS_IP_CROP_POSITIONLU')); + $cropposition[] = JHTML::_('select.option','1', JText::_('COM_JOOMGALLERY_CONFIG_GS_IP_CROP_POSITIONRU')); + $cropposition[] = JHTML::_('select.option','2', JText::_('COM_JOOMGALLERY_CONFIG_GS_IP_CROP_POSITIONC')); + $cropposition[] = JHTML::_('select.option','3', JText::_('COM_JOOMGALLERY_CONFIG_GS_IP_CROP_POSITIONLL')); + $cropposition[] = JHTML::_('select.option','4', JText::_('COM_JOOMGALLERY_CONFIG_GS_IP_CROP_POSITIONRL')); + $mc_jg_cropposition = JHTML::_('select.genericlist',$cropposition, 'jg_cropposition', 'class="inputbox" size="5"', 'value', 'text', $this->_config->jg_cropposition); + JHTML::_('joomconfig.row', 'jg_cropposition', 'custom', 'COM_JOOMGALLERY_CONFIG_GS_IP_CROP_POSITION', $mc_jg_cropposition); + JHTML::_('joomconfig.row', 'jg_thumbwidth', 'text', 'COM_JOOMGALLERY_CONFIG_GS_IP_THUMBNAIL_WIDTH', $this->_config->jg_thumbwidth); + JHTML::_('joomconfig.row', 'jg_thumbheight', 'text', 'COM_JOOMGALLERY_CONFIG_GS_IP_THUMBNAIL_HEIGHT', $this->_config->jg_thumbheight); + JHTML::_('joomconfig.row', 'jg_thumbquality', 'text', 'COM_JOOMGALLERY_CONFIG_GS_IP_THUMBNAIL_QUALITY', $this->_config->jg_thumbquality); +JHTML::_('joomconfig.end'); +endif; + +// start Tab "Grundlegende Einstellungen->Backend-Upload" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_GS_TAB_BACKEND_UPLOAD'), 'nested-four'); + +JHTML::_('joomconfig.start', 'page4'); + $uploadordering[] = JHTML::_('select.option','0', JText::_('COM_JOOMGALLERY_CONFIG_GS_BU_NO_ORDER')); + $uploadordering[] = JHTML::_('select.option','1', JText::_('COM_JOOMGALLERY_CONFIG_GS_BU_DESCENDING')); + $uploadordering[] = JHTML::_('select.option','2', JText::_('COM_JOOMGALLERY_CONFIG_GS_BU_ASCENDING')); + $mc_jg_uploadorder = JHTML::_('select.genericlist',$uploadordering, 'jg_uploadorder', 'class="inputbox" size="3"', 'value', 'text', $this->_config->jg_uploadorder); + JHTML::_('joomconfig.row', 'jg_uploadorder', 'custom', 'COM_JOOMGALLERY_CONFIG_GS_BU_UPLOAD_ORDER', $mc_jg_uploadorder); + JHTML::_('joomconfig.row', 'jg_useorigfilename', 'yesno', 'COM_JOOMGALLERY_CONFIG_COMMON_ORIGINAL_FILENAME', $this->_config->jg_useorigfilename); + JHTML::_('joomconfig.row', 'jg_filenamenumber', 'yesno', 'COM_JOOMGALLERY_CONFIG_GS_BU_FILENAMENUMBER', $this->_config->jg_filenamenumber); + $delete_original[] = JHTML::_('select.option','0', JText::_('JNO')); + $delete_original[] = JHTML::_('select.option','1', JText::_('COM_JOOMGALLERY_CONFIG_GS_BU_DELETE_ALL_ORIGINALS')); + $delete_original[] = JHTML::_('select.option','2', JText::_('COM_JOOMGALLERY_CONFIG_GS_BU_DELETE_ORIGINAL_CHECKBOX')); + $mc_jg_delete_original = JHTML::_('select.genericlist',$delete_original, 'jg_delete_original', 'class="inputbox" size="3"', 'value', 'text', $this->_config->jg_delete_original); + JHTML::_('joomconfig.row', 'jg_delete_original', 'custom', 'COM_JOOMGALLERY_CONFIG_GS_BU_DELETE_ORIGINAL', $mc_jg_delete_original); +JHTML::_('joomconfig.end'); + +// start Tab "Grundlegende Einstellungen->Benachrichtigungen" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_GS_TAB_MESSAGES_SETTINGS'), 'nested-five'); + +JHTML::_('joomconfig.start', 'page5'); + $message_type[] = JHTML::_('select.option', '0', JText::_('COM_JOOMGALLERY_CONFIG_GS_MS_OPTION_NONE')); + $message_type[] = JHTML::_('select.option', '1', JText::_('COM_JOOMGALLERY_CONFIG_GS_MS_OPTION_MAIL')); + $message_type[] = JHTML::_('select.option', '2', JText::_('COM_JOOMGALLERY_CONFIG_GS_MS_OPTION_PM')); + $message_type[] = JHTML::_('select.option', '3', JText::_('COM_JOOMGALLERY_CONFIG_GS_MS_OPTION_BOTH')); + $mc_jg_msg_upload_type = JHTML::_('select.genericlist', $message_type, 'jg_msg_upload_type', 'class="inputbox" size="4"', 'value', 'text', $this->_config->get('jg_msg_upload_type')); + JHTML::_('joomconfig.row', 'jg_msg_upload_type', 'custom', 'COM_JOOMGALLERY_CONFIG_GS_MS_UPLOAD_TYPE', $mc_jg_msg_upload_type); + $arr_jg_msg_upload_recipients = $this->_config->get('jg_msg_upload_recipients') ? explode(',', $this->_config->get('jg_msg_upload_recipients')) : array(-1); + $list = JHTML::_('joomselect.users', 'jg_msg_upload_recipients[]', $arr_jg_msg_upload_recipients, false, array(-1 => JText::_('COM_JOOMGALLERY_CONFIG_GS_MS_DEFAULT_RECIPIENTS'))); + JHTML::_('joomconfig.row', 'jg_msg_upload_recipients', 'custom', 'COM_JOOMGALLERY_CONFIG_GS_MS_UPLOAD_RECIPIENTS', $list, true, '', JText::_('COM_JOOMGALLERY_CONFIG_GS_MS_UPLOAD_RECIPIENTS_LONG').(JHtmlJoomSelect::$count > $this->_config->get('jg_use_listbox_max_user_count') ? '

    '.JText::sprintf('COM_JOOMGALLERY_CONFIG_GS_MS_RECIPIENTS_MANY_USERS', $this->_config->get('jg_use_listbox_max_user_count')) : '')); + $mc_jg_msg_download_type = JHTML::_('select.genericlist', $message_type, 'jg_msg_download_type', 'class="inputbox" size="4"', 'value', 'text', $this->_config->get('jg_msg_download_type')); + JHTML::_('joomconfig.row', 'jg_msg_download_type', 'custom', 'COM_JOOMGALLERY_CONFIG_GS_MS_DOWNLOAD_TYPE', $mc_jg_msg_download_type); + $arr_jg_msg_download_recipients = $this->_config->get('jg_msg_download_recipients') ? explode(',', $this->_config->get('jg_msg_download_recipients')) : array(-1); + $list = JHTML::_('joomselect.users', 'jg_msg_download_recipients[]', $arr_jg_msg_download_recipients, false, array(-1 => JText::_('COM_JOOMGALLERY_CONFIG_GS_MS_DEFAULT_RECIPIENTS'))); + JHTML::_('joomconfig.row', 'jg_msg_download_recipients', 'custom', 'COM_JOOMGALLERY_CONFIG_GS_MS_DOWNLOAD_RECIPIENTS', $list, true, '', JText::_('COM_JOOMGALLERY_CONFIG_GS_MS_DOWNLOAD_RECIPIENTS_LONG').(JHtmlJoomSelect::$count > $this->_config->get('jg_use_listbox_max_user_count') ? '

    '.JText::sprintf('COM_JOOMGALLERY_CONFIG_GS_MS_RECIPIENTS_MANY_USERS', $this->_config->get('jg_use_listbox_max_user_count')) : '')); + JHTML::_('joomconfig.row', 'jg_msg_zipdownload', 'yesno', 'COM_JOOMGALLERY_CONFIG_GS_MS_ZIPDOWNLOAD', $this->_config->jg_msg_zipdownload); + $mc_jg_msg_comment_type = JHTML::_('select.genericlist', $message_type, 'jg_msg_comment_type', 'class="inputbox" size="4"', 'value', 'text', $this->_config->get('jg_msg_comment_type')); + JHTML::_('joomconfig.row', 'jg_msg_comment_type', 'custom', 'COM_JOOMGALLERY_CONFIG_GS_MS_COMMENT_TYPE', $mc_jg_msg_comment_type); + $arr_jg_msg_comment_recipients = strlen($this->_config->get('jg_msg_comment_recipients')) ? explode(',', $this->_config->get('jg_msg_comment_recipients')) : array(-1); + $list = JHTML::_('joomselect.users', 'jg_msg_comment_recipients[]', $arr_jg_msg_comment_recipients, true, array(-1 => JText::_('COM_JOOMGALLERY_CONFIG_GS_MS_DEFAULT_RECIPIENTS'))); + JHTML::_('joomconfig.row', 'jg_msg_comment_recipients', 'custom', 'COM_JOOMGALLERY_CONFIG_GS_MS_COMMENT_RECIPIENTS', $list, true, '', JText::_('COM_JOOMGALLERY_CONFIG_GS_MS_COMMENT_RECIPIENTS_LONG').(JHtmlJoomSelect::$count > $this->_config->get('jg_use_listbox_max_user_count') ? '

    '.JText::sprintf('COM_JOOMGALLERY_CONFIG_GS_MS_RECIPIENTS_MANY_USERS', $this->_config->get('jg_use_listbox_max_user_count')).' '.JText::_('COM_JOOMGALLERY_CONFIG_GS_MS_RECIPIENTS_MANY_USERS_ADDITION') : '')); + JHTML::_('joomconfig.row', 'jg_msg_comment_toowner', 'yesno', 'COM_JOOMGALLERY_CONFIG_GS_MS_COMMENT_TOOWNER', $this->_config->get('jg_msg_comment_toowner')); + $mc_jg_msg_nametag_type = JHTML::_('select.genericlist', $message_type, 'jg_msg_nametag_type', 'class="inputbox" size="4"', 'value', 'text', $this->_config->get('jg_msg_nametag_type')); + JHTML::_('joomconfig.row', 'jg_msg_nametag_type', 'custom', 'COM_JOOMGALLERY_CONFIG_GS_MS_NAMETAG_TYPE', $mc_jg_msg_nametag_type); + $arr_jg_msg_nametag_recipients = strlen($this->_config->get('jg_msg_nametag_recipients')) ? explode(',', $this->_config->get('jg_msg_nametag_recipients')) : array(-1); + $list = JHTML::_('joomselect.users', 'jg_msg_nametag_recipients[]', $arr_jg_msg_nametag_recipients, true, array(-1 => JText::_('COM_JOOMGALLERY_CONFIG_GS_MS_DEFAULT_RECIPIENTS'))); + JHTML::_('joomconfig.row', 'jg_msg_nametag_recipients', 'custom', 'COM_JOOMGALLERY_CONFIG_GS_MS_NAMETAG_RECIPIENTS', $list, true, '', JText::_('COM_JOOMGALLERY_CONFIG_GS_MS_NAMETAG_RECIPIENTS_LONG').(JHtmlJoomSelect::$count > $this->_config->get('jg_use_listbox_max_user_count') ? '

    '.JText::sprintf('COM_JOOMGALLERY_CONFIG_GS_MS_RECIPIENTS_MANY_USERS', $this->_config->get('jg_use_listbox_max_user_count')).' '.JText::_('COM_JOOMGALLERY_CONFIG_GS_MS_RECIPIENTS_MANY_USERS_ADDITION') : '')); + JHTML::_('joomconfig.row', 'jg_msg_nametag_totaggeduser', 'yesno', 'COM_JOOMGALLERY_CONFIG_GS_MS_NAMETAG_TOTAGGEDUSER', $this->_config->get('jg_msg_nametag_totaggeduser')); + JHTML::_('joomconfig.row', 'jg_msg_nametag_toowner', 'yesno', 'COM_JOOMGALLERY_CONFIG_GS_MS_NAMETAG_TOOWNER', $this->_config->get('jg_msg_nametag_toowner')); + $mc_jg_msg_report_type = JHTML::_('select.genericlist', $message_type, 'jg_msg_report_type', 'class="inputbox" size="4"', 'value', 'text', $this->_config->get('jg_msg_report_type')); + JHTML::_('joomconfig.row', 'jg_msg_report_type', 'custom', 'COM_JOOMGALLERY_CONFIG_GS_MS_REPORT_TYPE', $mc_jg_msg_report_type); + $arr_jg_msg_report_recipients = $this->_config->get('jg_msg_report_recipients') ? explode(',', $this->_config->get('jg_msg_report_recipients')) : array(-1); + $list = JHTML::_('joomselect.users', 'jg_msg_report_recipients[]', $arr_jg_msg_report_recipients, false, array(-1 => JText::_('COM_JOOMGALLERY_CONFIG_GS_MS_DEFAULT_RECIPIENTS'))); + JHTML::_('joomconfig.row', 'jg_msg_report_recipients', 'custom', 'COM_JOOMGALLERY_CONFIG_GS_MS_REPORT_RECIPIENTS', $list, true, '', JText::_('COM_JOOMGALLERY_CONFIG_GS_MS_REPORT_RECIPIENTS_LONG').(JHtmlJoomSelect::$count > $this->_config->get('jg_use_listbox_max_user_count') ? '

    '.JText::sprintf('COM_JOOMGALLERY_CONFIG_GS_MS_RECIPIENTS_MANY_USERS', $this->_config->get('jg_use_listbox_max_user_count')) : '')); + JHTML::_('joomconfig.row', 'jg_msg_report_toowner', 'yesno', 'COM_JOOMGALLERY_CONFIG_GS_MS_REPORT_TOOWNER', $this->_config->get('jg_msg_report_toowner')); + unset($message_type[0]); + $mc_jg_msg_rejectimg_type = JHTML::_('select.genericlist', $message_type, 'jg_msg_rejectimg_type', 'class="inputbox" size="3"', 'value', 'text', $this->_config->get('jg_msg_rejectimg_type')); + JHTML::_('joomconfig.row', 'jg_msg_rejectimg_type', 'custom', 'COM_JOOMGALLERY_CONFIG_GS_MS_REJECTIMG_TYPE', $mc_jg_msg_rejectimg_type); + JHTML::_('joomconfig.row', 'jg_msg_global_from', 'yesno', 'COM_JOOMGALLERY_CONFIG_GS_MS_GLOBAL_FROM', $this->_config->get('jg_msg_global_from')); +JHTML::_('joomconfig.end'); + +// start Tab "Grundlegende Einstellungen->Performance Einstellungen" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_GS_TAB_PERFORMANCE_SETTINGS'), 'nested-six'); + +JHTML::_('joomconfig.start', 'page6'); + JHTML::_('joomconfig.row', 'jg_ajaxcategoryselection', 'yesno', 'COM_JOOMGALLERY_CONFIG_GS_PS_AJAXCATEGORYSELECTION', $this->_config->get('jg_ajaxcategoryselection')); + JHTML::_('joomconfig.row', 'jg_disableunrequiredchecks', 'yesno', 'COM_JOOMGALLERY_CONFIG_GS_PS_DISABLEUNREQUIREDCHECKS', $this->_config->get('jg_disableunrequiredchecks')); + JHTML::_('joomconfig.row', 'jg_use_listbox_max_user_count', 'text', 'COM_JOOMGALLERY_CONFIG_GS_PS_USELISTBOXMAXUSERCOUNT', $this->_config->get('jg_use_listbox_max_user_count')); +JHTML::_('joomconfig.end'); + +echo JHtml::_('tabs.end'); + +// start second nested MainTab "Benutzer-Rechte" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_TAB_USER_ACCESS_RIGHTS'), 'NestedMainPane2'); +// start second nested tabs pane +echo JHtml::_('tabs.start', 'NestedPaneTwo', array('useCookie' => 1)); +// start Tab "Benutzer-Rechte->Benutzer-Upload ueber 'Meine Galerie'" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_UR_UU_USER_UPLOAD_SETTINGS'), 'nested-seven'); + +JHTML::_('joomconfig.start', 'page7'); + JHTML::_('joomconfig.row', 'jg_userspace', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_UU_USERSPACE', $this->_config->jg_userspace); + $useruploaddefaultcat[] = JHTML::_('select.option','0', JText::_('JNONE')); + $useruploaddefaultcat[] = JHTML::_('select.option','1', JText::_('COM_JOOMGALLERY_CONFIG_UR_UU_DEFAULT_CAT_OLDEST_ALL')); + $useruploaddefaultcat[] = JHTML::_('select.option','2', JText::_('COM_JOOMGALLERY_CONFIG_UR_UU_DEFAULT_CAT_NEWEST_ALL')); + $useruploaddefaultcat[] = JHTML::_('select.option','3', JText::_('COM_JOOMGALLERY_CONFIG_UR_UU_DEFAULT_CAT_OLDEST_OWN')); + $useruploaddefaultcat[] = JHTML::_('select.option','4', JText::_('COM_JOOMGALLERY_CONFIG_UR_UU_DEFAULT_CAT_NEWEST_OWN')); + $mc_jg_useruploaddefaultcat = JHTML::_('select.genericlist', $useruploaddefaultcat, 'jg_useruploaddefaultcat', 'class="inputbox" size="5"', 'value', 'text', $this->_config->jg_useruploaddefaultcat); + JHTML::_('joomconfig.row', 'jg_useruploaddefaultcat', 'custom', 'COM_JOOMGALLERY_CONFIG_UR_UU_DEFAULT_CAT', $mc_jg_useruploaddefaultcat); + JHTML::_('joomconfig.row', 'jg_approve', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_UU_APPROVAL_NEEDED', $this->_config->jg_approve); + JHTML::_('joomconfig.row', 'jg_unregistered_permissions', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_UU_UNREGISTERED_PERMISSIONS', $this->_config->jg_unregistered_permissions); + JHTML::_('joomconfig.row', 'jg_usercatacc', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_UU_USERCATACCESS', $this->_config->jg_usercatacc); + JHTML::_('joomconfig.row', 'jg_usercatthumbalign', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_UU_USERCATTHUMBALIGN', $this->_config->jg_usercatthumbalign); + JHTML::_('joomconfig.row', 'jg_maxusercat', 'text', 'COM_JOOMGALLERY_CONFIG_UR_UU_MAX_USERCATS', $this->_config->jg_maxusercat); + JHTML::_('joomconfig.row', 'jg_maxuserimage', 'text', 'COM_JOOMGALLERY_CONFIG_UR_UU_MAX_IMAGES', $this->_config->jg_maxuserimage); + JHTML::_('joomconfig.row', 'jg_maxuserimage_timespan', 'text', 'COM_JOOMGALLERY_CONFIG_UR_UU_MAX_IMAGES_TIMESPAN', $this->_config->jg_maxuserimage_timespan); + JHTML::_('joomconfig.row', 'jg_maxfilesize', 'text', 'COM_JOOMGALLERY_CONFIG_UR_UU_MAX_FILESIZE', $this->_config->jg_maxfilesize); + JHTML::_('joomconfig.row', 'jg_useruploadsingle', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_UU_UPLOAD_SINGLE', $this->_config->jg_useruploadsingle); + JHTML::_('joomconfig.row', 'jg_maxuploadfields', 'text', 'COM_JOOMGALLERY_CONFIG_UR_UU_MAX_UPLOADFIELDS', $this->_config->jg_maxuploadfields); + JHTML::_('joomconfig.row', 'jg_useruploadajax', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_UU_UPLOAD_AJAX', $this->_config->jg_useruploadajax); + JHTML::_('joomconfig.row', 'jg_useruploadbatch', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_UU_UPLOAD_BATCH', $this->_config->jg_useruploadbatch); + JHTML::_('joomconfig.row', 'jg_useruploadjava', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_UU_UPLOAD_JAVA', $this->_config->jg_useruploadjava); + JHTML::_('joomconfig.row', 'jg_useruseorigfilename', 'yesno', 'COM_JOOMGALLERY_CONFIG_COMMON_ORIGINAL_FILENAME', $this->_config->jg_useruseorigfilename); + JHTML::_('joomconfig.row', 'jg_useruploadnumber', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_UU_NUMBERING', $this->_config->jg_useruploadnumber); + JHTML::_('joomconfig.row', 'jg_special_gif_upload', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_UU_SPECIAL_GIF_UPLOAD', $this->_config->jg_special_gif_upload); + $delete_original_user[] = JHTML::_('select.option','0', JText::_('JNO')); + $delete_original_user[] = JHTML::_('select.option','1', JText::_('COM_JOOMGALLERY_CONFIG_GS_BU_DELETE_ALL_ORIGINALS')); + $delete_original_user[] = JHTML::_('select.option','2', JText::_('COM_JOOMGALLERY_CONFIG_GS_BU_DELETE_ORIGINAL_CHECKBOX')); + $mc_jg_delete_original_user = JHTML::_('select.genericlist', $delete_original_user, 'jg_delete_original_user', 'class="inputbox" size="3"', 'value', 'text', $this->_config->jg_delete_original_user); + JHTML::_('joomconfig.row', 'jg_delete_original_user', 'custom', 'COM_JOOMGALLERY_CONFIG_GS_BU_DELETE_ORIGINAL', $mc_jg_delete_original_user); + JHTML::_('joomconfig.row', 'jg_newpiccopyright', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_UU_COPYRIGHT', $this->_config->jg_newpiccopyright); + JHTML::_('joomconfig.row', 'jg_newpicnote', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_UU_UPLOADNOTE', $this->_config->jg_newpicnote); + $redirect_after_upload[] = JHTML::_('select.option','0', JText::_('JNO')); + $redirect_after_upload[] = JHTML::_('select.option','1', JText::_('COM_JOOMGALLERY_CONFIG_GS_BU_REDIRECT_AFTER_UPLOAD_TO_UPLOAD_VIEW')); + $redirect_after_upload[] = JHTML::_('select.option','2', JText::_('COM_JOOMGALLERY_CONFIG_GS_BU_REDIRECT_AFTER_UPLOAD_TO_USERPANEL')); + $redirect_after_upload[] = JHTML::_('select.option','3', JText::_('COM_JOOMGALLERY_CONFIG_GS_BU_REDIRECT_AFTER_UPLOAD_TO_GALLERY_VIEW')); + $mc_jg_redirect_after_upload = JHTML::_('select.genericlist', $redirect_after_upload, 'jg_redirect_after_upload', 'class="inputbox" size="4"', 'value', 'text', $this->_config->jg_redirect_after_upload); + JHTML::_('joomconfig.row', 'jg_redirect_after_upload', 'custom', 'COM_JOOMGALLERY_CONFIG_GS_BU_REDIRECT_AFTER_UPLOAD', $mc_jg_redirect_after_upload); + JHtml::_('joomconfig.row', 'jg_edit_metadata', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_UU_EDIT_METADATA', $this->_config->jg_edit_metadata); +JHTML::_('joomconfig.end'); + +// start Tab "Benutzer-Rechte->Download" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_UR_UD_USER_DOWNLOAD_SETTINGS'), 'nested-seven1'); + +JHTML::_('joomconfig.start', 'page71'); + JHTML::_('joomconfig.row', 'jg_download', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_UD_DOWNLOAD', $this->_config->jg_download); + JHTML::_('joomconfig.row', 'jg_download_unreg', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_UD_DOWNLOAD_UNREG', $this->_config->jg_download_unreg, $this->display); + JHTML::_('joomconfig.row', 'jg_download_hint', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_UD_DOWNLOAD_HINT', $this->_config->jg_download_hint); + $downloadfile[] = JHTML::_('select.option', 0, JText::_('COM_JOOMGALLERY_CONFIG_UR_UD_DETAIL_ONLY')); + $downloadfile[] = JHTML::_('select.option', 1, JText::_('COM_JOOMGALLERY_CONFIG_UR_UD_ORIGINAL_ONLY')); + $downloadfile[] = JHTML::_('select.option', 2, JText::_('COM_JOOMGALLERY_CONFIG_UR_UD_DETAIL_IFNO_ORIGINAL')); + $mc_jg_downloadfile = JHTML::_('select.genericlist', $downloadfile, 'jg_downloadfile', 'class="inputbox" size="3"', 'value', 'text', $this->_config->jg_downloadfile); + JHTML::_('joomconfig.row', 'jg_downloadfile', 'custom', 'COM_JOOMGALLERY_CONFIG_UR_UD_DOWNLOADFILE', $mc_jg_downloadfile); + JHTML::_('joomconfig.row', 'jg_downloadwithwatermark', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_UD_DOWNLOADWITHWATERMARK', $this->_config->jg_downloadwithwatermark); +JHTML::_('joomconfig.end'); + +// start Tab "Benutzer-Rechte->Bewertungen" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_UR_TAB_RATING_SETTINGS'), 'nested-eight'); + +JHTML::_('joomconfig.start', 'page8'); + JHTML::_('joomconfig.row', 'jg_showrating', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_RT_RATING', $this->_config->jg_showrating); + JHTML::_('joomconfig.row', 'jg_maxvoting', 'text', 'COM_JOOMGALLERY_CONFIG_UR_RT_HIGHEST_RATING', $this->_config->jg_maxvoting); + + $ratingcalctype[] = JHTML::_('select.option','0', JText::_('COM_JOOMGALLERY_CONFIG_UR_RT_CALC_TYPE_STANDARD')); + $ratingcalctype[] = JHTML::_('select.option','1', JText::_('COM_JOOMGALLERY_CONFIG_UR_RT_CALC_TYPE_BAYES1')); + $mc_jg_ratingcalctype = JHTML::_('select.genericlist', $ratingcalctype, 'jg_ratingcalctype', 'class="inputbox" size="2"', 'value', 'text', $this->_config->jg_ratingcalctype); + JHTML::_('joomconfig.row', 'jg_ratingcalctype', 'custom', 'COM_JOOMGALLERY_CONFIG_UR_RT_CALC_TYPE', $mc_jg_ratingcalctype); + $ratingdisplaytype[] = JHTML::_('select.option','0', JText::_('COM_JOOMGALLERY_CONFIG_UR_RT_DISPLAY_TYPE_TEXT')); + $ratingdisplaytype[] = JHTML::_('select.option','1', JText::_('COM_JOOMGALLERY_CONFIG_UR_RT_DISPLAY_TYPE_GRAPHIC')); + $mc_jg_ratingdisplaytype = JHTML::_('select.genericlist', $ratingdisplaytype, 'jg_ratingdisplaytype', 'class="inputbox" size="2"', 'value', 'text', $this->_config->jg_ratingdisplaytype); + JHTML::_('joomconfig.row', 'jg_ratingdisplaytype', 'custom', 'COM_JOOMGALLERY_CONFIG_UR_RT_DISPLAY_TYPE', $mc_jg_ratingdisplaytype); + JHTML::_('joomconfig.row', 'jg_ajaxrating', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_RT_AJAX', $this->_config->jg_ajaxrating); + JHTML::_('joomconfig.row', 'jg_votingonlyonce', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_RT_VOTING_ONLY_ONCE', $this->_config->jg_votingonlyonce); + JHTML::_('joomconfig.row', 'jg_votingonlyreg', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_RT_VOTING_ONLY_REG', $this->_config->jg_votingonlyreg); + JHTML::_('joomconfig.end'); + +// start Tab "Benutzer-Rechte->Kommentare" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_UR_TAB_COMMENT_SETTINGS'), 'nested-nine'); + +JHTML::_('joomconfig.start', 'page9'); + JHTML::_('joomconfig.row', 'jg_showcomment', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_CM_COMMENTS', $this->_config->jg_showcomment); + JHTML::_('joomconfig.row', 'jg_anoncomment', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_CM_ANONYM', $this->_config->jg_anoncomment, $this->display); + JHTML::_('joomconfig.row', 'jg_namedanoncomment', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_CM_NAMED_ANONYM', $this->_config->jg_namedanoncomment, $this->display); + JHTML::_('joomconfig.row', 'jg_anonapprovecom', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_CM_APPROVE_NEEDED_ANONYM', $this->_config->get('jg_anonapprovecom'), $this->display); + JHTML::_('joomconfig.row', 'jg_approvecom', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_CM_APPROVE_NEEDED', $this->_config->jg_approvecom); + JHTML::_('joomconfig.row', 'jg_bbcodesupport', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_CM_BBCODE', $this->_config->jg_bbcodesupport); + JHTML::_('joomconfig.row', 'jg_smiliesupport', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_CM_SMILIES', $this->_config->jg_smiliesupport); + JHTML::_('joomconfig.row', 'jg_anismilie', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_CM_ANISMILIES', $this->_config->jg_anismilie); + $smiliescolor[] = JHTML::_('select.option','grey', JText::_('COM_JOOMGALLERY_CONFIG_UR_CM_COLOR_GREY')); + $smiliescolor[] = JHTML::_('select.option','orange', JText::_('COM_JOOMGALLERY_CONFIG_UR_CM_COLOR_ORANGE')); + $smiliescolor[] = JHTML::_('select.option','yellow', JText::_('COM_JOOMGALLERY_CONFIG_UR_CM_COLOR_YELLOW')); + $smiliescolor[] = JHTML::_('select.option','blue', JText::_('COM_JOOMGALLERY_CONFIG_UR_CM_COLOR_BLUE')); + $mc_jg_smiliescolor = JHTML::_('select.genericlist',$smiliescolor, 'jg_smiliescolor', 'class="inputbox" size="4"', 'value', 'text', $this->_config->jg_smiliescolor); + JHTML::_('joomconfig.row', 'jg_smiliescolor', 'custom', 'COM_JOOMGALLERY_CONFIG_UR_CM_COLORSMILIES', $mc_jg_smiliescolor); +JHTML::_('joomconfig.end'); + +// start Tab "Benutzer-Rechte->Beanstandungen" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_UR_RP_REPORTS_SETTINGS'), 'nested-nine1'); + +JHTML::_('joomconfig.start', 'page91'); + JHTML::_('joomconfig.row', 'jg_report_images', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_RP_REPORT_IMAGES', $this->_config->jg_report_images); + JHTML::_('joomconfig.row', 'jg_report_unreg', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_RP_REPORT_UNREG', $this->_config->jg_report_unreg); + JHTML::_('joomconfig.row', 'jg_report_hint', 'yesno', 'COM_JOOMGALLERY_CONFIG_UR_RP_REPORT_HINT', $this->_config->jg_report_hint); +JHTML::_('joomconfig.end'); + +echo JHtml::_('tabs.end'); + +// start third nested MainTab "Frontend Einstellungen" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_TAB_FRONTEND_SETTINGS'), 'NestedMainPane3'); +// start third nested tabs pane +echo JHtml::_('tabs.start', 'NestedPaneThree', array('useCookie' => 1)); +// start Tab "Frontend Einstellungen->Generelle Einstellungen +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_TAB_GENERAL_SETTINGS'), 'nested-ten'); + +JHTML::_('joomconfig.start', 'page10'); + JHTML::_('joomconfig.row', 'jg_itemid', 'text', 'COM_JOOMGALLERY_CONFIG_FS_GS_ITEMID', $this->_config->get('jg_itemid')); + JHTML::_('joomconfig.row', 'jg_alternative_layout', 'custom', 'COM_JOOMGALLERY_CONFIG_FS_GS_ALTERNATIVE_LAYOUT', $this->getComponentLayouts($this->_config->get('jg_alternative_layout'))); + JHTML::_('joomconfig.row', 'jg_anchors', 'yesno', 'COM_JOOMGALLERY_CONFIG_FS_GS_ANCHORS', $this->_config->jg_anchors); + $tooltips[] = JHTML::_('select.option', 0, JText::_('COM_JOOMGALLERY_CONFIG_FS_GS_TOOLTIPS_OPTION_NO_DISPLAY')); + $tooltips[] = JHTML::_('select.option', 1, JText::_('COM_JOOMGALLERY_CONFIG_FS_GS_TOOLTIPS_OPTION_DEFAULT_STYLE')); + $tooltips[] = JHTML::_('select.option', 2, JText::_('COM_JOOMGALLERY_CONFIG_FS_GS_TOOLTIPS_OPTION_OWN_STYLE')); + $mc_jg_tooltips = JHTML::_('select.genericlist', $tooltips, 'jg_tooltips', 'class="inputbox" size="3"', 'value', 'text', $this->_config->jg_tooltips); + JHTML::_('joomconfig.row', 'jg_tooltips', 'custom', 'COM_JOOMGALLERY_CONFIG_FS_GS_TOOLTIPS', $mc_jg_tooltips); + JHTML::_('joomconfig.row', 'jg_contentpluginsenabled', 'yesno', 'COM_JOOMGALLERY_CONFIG_FS_GS_CONTENTPLUGINS', $this->_config->get('jg_contentpluginsenabled')); + JHTML::_('joomconfig.row', 'jg_imgalign', 'text', 'COM_JOOMGALLERY_CONFIG_FS_GS_IMG_ALIGN', $this->_config->jg_imgalign); + JHTML::_('joomconfig.row', 'jg_dyncrop', 'yesno', 'COM_JOOMGALLERY_CONFIG_FS_GS_DYNCROP', $this->_config->jg_dyncrop); + $dyncropposition[] = JHTML::_('select.option','0', JText::_('COM_JOOMGALLERY_CONFIG_GS_IP_CROP_POSITIONLU')); + $dyncropposition[] = JHTML::_('select.option','1', JText::_('COM_JOOMGALLERY_CONFIG_GS_IP_CROP_POSITIONRU')); + $dyncropposition[] = JHTML::_('select.option','2', JText::_('COM_JOOMGALLERY_CONFIG_GS_IP_CROP_POSITIONC')); + $dyncropposition[] = JHTML::_('select.option','3', JText::_('COM_JOOMGALLERY_CONFIG_GS_IP_CROP_POSITIONLL')); + $dyncropposition[] = JHTML::_('select.option','4', JText::_('COM_JOOMGALLERY_CONFIG_GS_IP_CROP_POSITIONRL')); + $mc_jg_dyncropposition = JHTML::_('select.genericlist', $dyncropposition, 'jg_dyncropposition', 'class="inputbox" size="5"', 'value', 'text', $this->_config->jg_dyncropposition); + JHTML::_('joomconfig.row', 'jg_dyncropposition', 'custom', 'COM_JOOMGALLERY_CONFIG_FS_GS_DYNCROP_POSITION', $mc_jg_dyncropposition); + JHTML::_('joomconfig.row', 'jg_dyncropwidth', 'text', 'COM_JOOMGALLERY_CONFIG_FS_GS_DYNCROP_WIDTH', $this->_config->jg_dyncropwidth); + JHTML::_('joomconfig.row', 'jg_dyncropheight', 'text', 'COM_JOOMGALLERY_CONFIG_FS_GS_DYNCROP_HEIGHT', $this->_config->jg_dyncropheight); + $mc_color_value = JHTML::_('joomgallery.colorpicker', 'jg_dyncropbgcol', $this->_config->jg_dyncropbgcol); + JHTML::_('joomconfig.row', 'jg_dyncropbgcol', 'custom', 'COM_JOOMGALLERY_CONFIG_FS_GS_DYNCROP_BGCOL', $mc_color_value); + $mc_color_value = ''; + $hideemptycats[] = JHTML::_('select.option', 0, JText::_('JNO')); + $hideemptycats[] = JHTML::_('select.option', 1, JText::_('COM_JOOMGALLERY_CONFIG_FS_GS_HIDE_ONLY_COMPLETELY_EMPTY_CATEGORIES')); + $hideemptycats[] = JHTML::_('select.option', 2, JText::_('COM_JOOMGALLERY_CONFIG_FS_GS_HIDE_ALL_EMPTY_CATEGORIES')); + $mc_jg_hideemptycats = JHTML::_('select.genericlist', $hideemptycats, 'jg_hideemptycats', 'class="inputbox" size="3"', 'value', 'text', $this->_config->jg_hideemptycats); + JHTML::_('joomconfig.row', 'jg_hideemptycats', 'custom', 'COM_JOOMGALLERY_CONFIG_FS_GS_HIDE_EMPTY_CATEGORIES', $mc_jg_hideemptycats); + JHTML::_('joomconfig.row', 'jg_skipcatview', 'yesno', 'COM_JOOMGALLERY_CONFIG_FS_GS_SKIPCATVIEW', $this->_config->jg_skipcatview); + JHTML::_('joomconfig.row', 'jg_showrestrictedcats', 'yesno', 'COM_JOOMGALLERY_CONFIG_FS_GS_SHOW_RESTRICTED_CATEGORIES', $this->_config->jg_showrestrictedcats); + JHTML::_('joomconfig.row', 'jg_showrestrictedhint', 'yesno', 'COM_JOOMGALLERY_CONFIG_FS_GS_SHOW_RESTRICTED_CATEGORIES_HINT', $this->_config->jg_showrestrictedhint); + JHTML::_('joomconfig.row', 'jg_realname', 'yesno', 'COM_JOOMGALLERY_CONFIG_FS_GS_USERNAME_REALNAME', $this->_config->jg_realname); + JHTML::_('joomconfig.row', 'jg_showowner', 'yesno', 'COM_JOOMGALLERY_CONFIG_FS_GF_OWNER', $this->_config->jg_showowner); +JHTML::_('joomconfig.end'); + +// start Tab "Frontend Einstellungen->Anordnung der Bilder" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_FS_TAB_IMAGE_ORDERING'), 'nested-eleven'); + +JHTML::_('joomconfig.start', 'page10'); + JHTML::_('joomconfig.intro', JText::_('COM_JOOMGALLERY_CONFIG_FS_IO_INTRO')); + $picorder[] = JHTML::_('select.option', JoomConfig::getValidImageSortingOrderByClauses(0), JText::_('COM_JOOMGALLERY_COMMON_OPTION_ORDERBY_ORDERING_ASC')); + $picorder[] = JHTML::_('select.option', JoomConfig::getValidImageSortingOrderByClauses(1), JText::_('COM_JOOMGALLERY_COMMON_OPTION_ORDERBY_ORDERING_DESC')); + $picorder[] = JHTML::_('select.option', JoomConfig::getValidImageSortingOrderByClauses(2), JText::_('COM_JOOMGALLERY_COMMON_OPTION_ORDERBY_UPLOADTIME_ASC')); + $picorder[] = JHTML::_('select.option', JoomConfig::getValidImageSortingOrderByClauses(3), JText::_('COM_JOOMGALLERY_COMMON_OPTION_ORDERBY_UPLOADTIME_DESC')); + $picorder[] = JHTML::_('select.option', JoomConfig::getValidImageSortingOrderByClauses(4), JText::_('COM_JOOMGALLERY_COMMON_OPTION_ORDERBY_IMGTITLE_ASC')); + $picorder[] = JHTML::_('select.option', JoomConfig::getValidImageSortingOrderByClauses(5), JText::_('COM_JOOMGALLERY_COMMON_OPTION_ORDERBY_IMGTITLE_DESC')); + $mc_jg_firstorder = JHTML::_('select.genericlist',$picorder, 'jg_firstorder', 'class="inputbox" size="1"', 'value', 'text', $this->_config->jg_firstorder); + JHTML::_('joomconfig.row', 'jg_firstorder', 'custom', 'COM_JOOMGALLERY_CONFIG_FS_IO_FIRST', $mc_jg_firstorder); + array_unshift($picorder, JHTML::_('select.option','', JText::_('COM_JOOMGALLERY_CONFIG_FS_IO_EMPTY'))); + $mc_jg_secondorder = JHTML::_('select.genericlist', $picorder, 'jg_secondorder', 'class="inputbox" size="1"', 'value', 'text', $this->_config->jg_secondorder); + JHTML::_('joomconfig.row', 'jg_secondorder', 'custom', 'COM_JOOMGALLERY_CONFIG_FS_IO_SECOND', $mc_jg_secondorder); + $mc_jg_thirdorder = JHTML::_('select.genericlist', $picorder, 'jg_thirdorder', 'class="inputbox" size="1"', 'value', 'text', $this->_config->jg_thirdorder); + JHTML::_('joomconfig.row', 'jg_thirdorder', 'custom', 'COM_JOOMGALLERY_CONFIG_FS_IO_THIRD', $mc_jg_thirdorder); +JHTML::_('joomconfig.end'); + +// start Tab "Frontend Einstellungen->Seitentitel" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_FS_TAB_PAGETITLE_SETTINGS'), 'nested-twelve'); + +JHTML::_('joomconfig.start', 'page11'); + JHTML::_('joomconfig.intro', JText::_('COM_JOOMGALLERY_CONFIG_FS_PT_PAGETITLE_SETTINGS_INTRO')); + JHTML::_('joomconfig.row', 'jg_pagetitle_cat', 'text', 'COM_JOOMGALLERY_CONFIG_FS_PT_CATVIEW', $this->_config->jg_pagetitle_cat, true, 'size = "60"'); + JHTML::_('joomconfig.row', 'jg_pagetitle_detail', 'text', 'COM_JOOMGALLERY_CONFIG_FS_PT_DETAILVIEW', $this->_config->jg_pagetitle_detail, true, 'size = "60"'); +JHTML::_('joomconfig.end'); + +// start Tab "Frontend Einstellungen->Kopf- und Fussbereich" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_FS_TAB_HEADER_AND_FOOTER'), 'nested-thirteen'); + +JHTML::_('joomconfig.start', 'page12'); + JHTML::_('joomconfig.intro', JText::_('COM_JOOMGALLERY_CONFIG_FS_HF_INTRO')); + JHTML::_('joomconfig.row', 'jg_showgalleryhead', 'yesno', 'COM_JOOMGALLERY_CONFIG_FS_HF_GALLERYHEAD', $this->_config->jg_showgalleryhead); + $pathway[] = JHTML::_('select.option','0', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_NO_DISPLAY')); + $pathway[] = JHTML::_('select.option','1', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_IN_HEADER')); + $pathway[] = JHTML::_('select.option','2', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_IN_FOOTER')); + $pathway[] = JHTML::_('select.option','3', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_IN_HEADERFOOTER')); + $mc_jg_showpathway = JHTML::_('select.genericlist', $pathway, 'jg_showpathway', 'class="inputbox" size="4"', 'value', 'text', $this->_config->jg_showpathway); + JHTML::_('joomconfig.row', 'jg_showpathway', 'custom', 'COM_JOOMGALLERY_CONFIG_FS_HF_PATHWAY', $mc_jg_showpathway); + JHTML::_('joomconfig.row', 'jg_completebreadcrumbs', 'yesno', 'COM_JOOMGALLERY_CONFIG_FS_HF_BREADCRUMBS', $this->_config->jg_completebreadcrumbs); + $shownumbpics[] = JHTML::_('select.option','0', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_NO_DISPLAY')); + $shownumbpics[] = JHTML::_('select.option','1', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_IN_HEADER')); + $shownumbpics[] = JHTML::_('select.option','2', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_IN_FOOTER')); + $shownumbpics[] = JHTML::_('select.option','3', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_IN_HEADERFOOTER')); + $mc_jg_showallpics = JHTML::_('select.genericlist', $shownumbpics, 'jg_showallpics', 'class="inputbox" size="4"', 'value', 'text', $this->_config->jg_showallpics); + JHTML::_('joomconfig.row', 'jg_showallpics', 'custom', 'COM_JOOMGALLERY_CONFIG_FS_HF_ALLIMAGES', $mc_jg_showallpics); + $shownumbhits[] = JHTML::_('select.option', '0', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_NO_DISPLAY')); + $shownumbhits[] = JHTML::_('select.option', '1', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_IN_HEADER')); + $shownumbhits[] = JHTML::_('select.option', '2', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_IN_FOOTER')); + $shownumbhits[] = JHTML::_('select.option', '3', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_IN_HEADERFOOTER')); + $mc_jg_showallhits = JHTML::_('select.genericlist', $shownumbhits, 'jg_showallhits', 'class="inputbox" size="4"', 'value', 'text', $this->_config->jg_showallhits); + JHTML::_('joomconfig.row', 'jg_showallhits', 'custom', 'COM_JOOMGALLERY_CONFIG_FS_HF_ALLHITS', $mc_jg_showallhits); + $showbacklink[] = JHTML::_('select.option', '0', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_NO_DISPLAY')); + $showbacklink[] = JHTML::_('select.option', '1', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_IN_HEADER')); + $showbacklink[] = JHTML::_('select.option', '2', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_IN_FOOTER')); + $showbacklink[] = JHTML::_('select.option', '3', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_IN_HEADERFOOTER')); + $mc_jg_showbacklink = JHTML::_('select.genericlist', $showbacklink, 'jg_showbacklink', 'class="inputbox" size="4"', 'value', 'text', $this->_config->jg_showbacklink); + JHTML::_('joomconfig.row', 'jg_showbacklink', 'custom', 'COM_JOOMGALLERY_CONFIG_FS_HF_BACKLINK', $mc_jg_showbacklink); + JHTML::_('joomconfig.row', 'jg_suppresscredits', 'yesno', 'COM_JOOMGALLERY_CONFIG_FS_HF_CREDITS', $this->_config->jg_suppresscredits); +JHTML::_('joomconfig.end'); + +// start Tab "Frontend Einstellungen->Meine Galerie" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_FS_TAB_USER_PANEL'), 'nested-fourteen'); + +JHTML::_('joomconfig.start', 'page13'); + JHTML::_('joomconfig.row', 'jg_showuserpanel', 'yesno', 'COM_JOOMGALLERY_CONFIG_FS_UP_USER_PANEL', $this->_config->jg_showuserpanel); + JHTML::_('joomconfig.row', 'jg_showuserpanel_hint', 'yesno', 'COM_JOOMGALLERY_CONFIG_FS_UP_USER_PANEL_HINT', $this->_config->jg_showuserpanel_hint); + JHTML::_('joomconfig.row', 'jg_showuserpanel_unreg', 'yesno', 'COM_JOOMGALLERY_CONFIG_FS_UP_USER_PANEL_UNREG', $this->_config->jg_showuserpanel_unreg, $this->display); + JHTML::_('joomconfig.row', 'jg_showallpicstoadmin', 'yesno', 'COM_JOOMGALLERY_CONFIG_FS_UP_ALLIMAGESTOADMIN', $this->_config->jg_showallpicstoadmin); + JHTML::_('joomconfig.row', 'jg_showminithumbs', 'yesno', 'COM_JOOMGALLERY_CONFIG_FS_UP_MINITHUMBS', $this->_config->jg_showminithumbs); +JHTML::_('joomconfig.end'); + +// start Tab "Frontend Einstellungen->PopUp-Funktionen" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_FS_TAB_POPUP_FUNCTIONS'), 'nested-fifteen'); + +JHTML::_('joomconfig.start', 'page14'); + JHTML::_('joomconfig.row', 'jg_openjs_padding', 'text', 'COM_JOOMGALLERY_CONFIG_FS_PF_OPENJS_BORDERPX', $this->_config->jg_openjs_padding); + $mc_color_value = JHTML::_('joomgallery.colorpicker', 'jg_openjs_background', $this->_config->jg_openjs_background); + JHTML::_('joomconfig.row', 'jg_openjs_background', 'custom', 'COM_JOOMGALLERY_CONFIG_FS_PF_OPENJS_BACKGROUND', $mc_color_value); + $mc_color_value = JHTML::_('joomgallery.colorpicker', 'jg_dhtml_border', $this->_config->jg_dhtml_border); + JHTML::_('joomconfig.row', 'jg_dhtml_border', 'custom', 'COM_JOOMGALLERY_CONFIG_FS_PF_DHTML_BORDER', $mc_color_value); + $mc_color_value = ''; + JHTML::_('joomconfig.row', 'jg_show_title_in_popup', 'yesno', 'COM_JOOMGALLERY_CONFIG_FS_PF_POPUP_TITLE', $this->_config->jg_show_title_in_popup); + $showdescinpopup[] = JHTML::_('select.option','0', JText::_('JNO')); + $showdescinpopup[] = JHTML::_('select.option','1', JText::_('COM_JOOMGALLERY_CONFIG_FS_PF_POPUP_DESCRIPTION_YHTML')); + $showdescinpopup[] = JHTML::_('select.option','2', JText::_('COM_JOOMGALLERY_CONFIG_FS_PF_POPUP_DESCRIPTION_YNOHTML')); + $mc_jg_show_description_in_popup = JHTML::_('select.genericlist', $showdescinpopup, 'jg_show_description_in_popup', 'class="inputbox" size="3"', 'value', 'text', $this->_config->jg_show_description_in_popup); + JHTML::_('joomconfig.row', 'jg_show_description_in_popup', 'custom', 'COM_JOOMGALLERY_CONFIG_FS_PF_POPUP_DESCRIPTION', $mc_jg_show_description_in_popup); + JHTML::_('joomconfig.row', 'jg_lightbox_speed', 'text', 'COM_JOOMGALLERY_CONFIG_FS_PF_SLIMBOX_SPEED', $this->_config->jg_lightbox_speed); + JHTML::_('joomconfig.row', 'jg_lightbox_slide_all', 'yesno', 'COM_JOOMGALLERY_CONFIG_FS_PF_SLIDEALL', $this->_config->jg_lightbox_slide_all); + JHTML::_('joomconfig.row', 'jg_resize_js_image', 'yesno', 'COM_JOOMGALLERY_CONFIG_FS_PF_JSIMAGERESIZE', $this->_config->jg_resize_js_image); + JHTML::_('joomconfig.row', 'jg_disable_rightclick_original', 'yesno', 'COM_JOOMGALLERY_CONFIG_FS_PF_DISABLE_RIGHTCLICK', $this->_config->jg_disable_rightclick_original); +JHTML::_('joomconfig.end'); + +echo JHtml::_('tabs.end'); + +// start fourth nested MainTab "Galerie-Ansicht" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_TAB_GALLERY_VIEW'), 'NestedMainPane4'); +// start fourth nested tabs pane +echo JHtml::_('tabs.start', 'NestedPaneFour', array('useCookie' => 1)); +// start Tab "Galerie-Ansicht->Generelle Einstellungen" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_TAB_GENERAL_SETTINGS'), 'nested-sixteen'); + +JHTML::_('joomconfig.start', 'page15'); + JHTML::_('joomconfig.row', 'jg_showgallerysubhead', 'yesno', 'COM_JOOMGALLERY_CONFIG_GV_GS_PATHWAY', $this->_config->jg_showgallerysubhead); + JHTML::_('joomconfig.row', 'jg_showallcathead', 'yesno', 'COM_JOOMGALLERY_CONFIG_GV_GS_CATEGORYHEADER', $this->_config->jg_showallcathead); + JHTML::_('joomconfig.row', 'jg_colcat', 'text', 'COM_JOOMGALLERY_CONFIG_GV_GS_NUMB_COLUMN', $this->_config->jg_colcat); + JHTML::_('joomconfig.row', 'jg_catperpage', 'text', 'COM_JOOMGALLERY_CONFIG_GV_GS_CATS_PER_PAGE', $this->_config->jg_catperpage); + JHTML::_('joomconfig.row', 'jg_ordercatbyalpha', 'yesno', 'COM_JOOMGALLERY_CONFIG_GV_GS_CATS_BY_ALPHA', $this->_config->jg_ordercatbyalpha); + $showpagecatnavi[] = JHTML::_('select.option', '1', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_TOP_ONLY')); + $showpagecatnavi[] = JHTML::_('select.option', '2', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_TOP_AND_BOTTOM')); + $showpagecatnavi[] = JHTML::_('select.option', '3', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_BOTTOM_ONLY')); + $mc_jg_showgallerypagenav = JHTML::_('select.genericlist', $showpagecatnavi, 'jg_showgallerypagenav', 'class="inputbox" size="3"', 'value', 'text', $this->_config->jg_showgallerypagenav); + JHTML::_('joomconfig.row', 'jg_showgallerypagenav', 'custom', 'COM_JOOMGALLERY_CONFIG_GV_GS_PAGENAVIGATION', $mc_jg_showgallerypagenav); + JHTML::_('joomconfig.row', 'jg_showcatcount', 'yesno', 'COM_JOOMGALLERY_CONFIG_GV_GS_NUMB_CATS', $this->_config->jg_showcatcount); + $catthumbs[] = JHTML::_('select.option', '0', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_NONE')); + $catthumbs[] = JHTML::_('select.option', '1', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_RANDOM')); + $catthumbs[] = JHTML::_('select.option', '2', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_MYCHOISE')); + $catthumbs[] = JHTML::_('select.option', '3', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_OVERRIDE')); + $mc_jg_showcatthumb = JHTML::_('select.genericlist', $catthumbs, 'jg_showcatthumb', 'class="inputbox" size="4"', 'value', 'text', $this->_config->jg_showcatthumb); + JHTML::_('joomconfig.row', 'jg_showcatthumb', 'custom', 'COM_JOOMGALLERY_CONFIG_COMMON_CATEGORYTHUMBNAIL', $mc_jg_showcatthumb); + $randomcatthumbs[] = JHTML::_('select.option', '1', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_FROM_PARENT_CAT_ONLY')); + $randomcatthumbs[] = JHTML::_('select.option', '2', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_FROM_CHILD_CAT_ONLY')); + $randomcatthumbs[] = JHTML::_('select.option', '3', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_FROM_BOTH')); + $mc_jg_showrandomcatthumb = JHTML::_('select.genericlist', $randomcatthumbs, 'jg_showrandomcatthumb', 'class="inputbox" size="3"', 'value', 'text', $this->_config->jg_showrandomcatthumb); + JHTML::_('joomconfig.row', 'jg_showrandomcatthumb', 'custom', 'COM_JOOMGALLERY_CONFIG_COMMON_RANDOMCATTHUMB', $mc_jg_showrandomcatthumb); + $cthumbalign[] = JHTML::_('select.option', '1', JText::_('COM_JOOMGALLERY_COMMON_OPTION_FLUSH_LEFT')); + $cthumbalign[] = JHTML::_('select.option', '2', JText::_('COM_JOOMGALLERY_COMMON_OPTION_FLUSH_RIGHT')); + $cthumbalign[] = JHTML::_('select.option', '0', JText::_('COM_JOOMGALLERY_COMMON_OPTION_CHANGING')); + $cthumbalign[] = JHTML::_('select.option', '3', JText::_('COM_JOOMGALLERY_COMMON_OPTION_CENTERED')); + $mc_jg_ctalign = JHTML::_('select.genericlist', $cthumbalign, 'jg_ctalign', 'class="inputbox" size="4"', 'value', 'text', $this->_config->jg_ctalign); + JHTML::_('joomconfig.row', 'jg_ctalign', 'custom', 'COM_JOOMGALLERY_CONFIG_COMMON_THUMBALIGN', $mc_jg_ctalign); + JHTML::_('joomconfig.row', 'jg_showtotalcatimages', 'yesno', 'COM_JOOMGALLERY_CONFIG_COMMON_CATEGORY_IMAGES', $this->_config->jg_showtotalcatimages); + JHTML::_('joomconfig.row', 'jg_showtotalcathits', 'yesno', 'COM_JOOMGALLERY_CONFIG_COMMON_CATEGORY_HITS', $this->_config->jg_showtotalcathits); + JHTML::_('joomconfig.row', 'jg_showcatasnew', 'yesno', 'COM_JOOMGALLERY_CONFIG_GV_GS_CATASNEW', $this->_config->jg_showcatasnew); + JHTML::_('joomconfig.row', 'jg_catdaysnew', 'text', 'COM_JOOMGALLERY_CONFIG_GV_GS_CATDAYSNEW', $this->_config->jg_catdaysnew); + JHTML::_('joomconfig.row', 'jg_showdescriptioningalleryview', 'yesno', 'COM_JOOMGALLERY_CONFIG_GV_GS_DESCRIPTION', $this->_config->get('jg_showdescriptioningalleryview')); + JHTML::_('joomconfig.row', 'jg_uploadicongallery', 'yesno', 'COM_JOOMGALLERY_CONFIG_COMMON_UPLOAD_ICON', $this->_config->get('jg_uploadicongallery')); + JHTML::_('joomconfig.row', 'jg_showsubsingalleryview', 'yesno', 'COM_JOOMGALLERY_CONFIG_GV_GS_SUBCATEGORIES', $this->_config->jg_showsubsingalleryview); +JHTML::_('joomconfig.end'); + +echo JHtml::_('tabs.end'); + +// start fifth nested MainTab "Kategorie-Ansicht" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_TAB_CATEGORY_VIEW'), 'NestedMainPane5'); +// start fifth nested tabs pane +echo JHtml::_('tabs.start', 'NestedPaneFive', array('useCookie' => 1)); +// start Tab "Kategorie-Ansicht->Generelle Einstellungen" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_TAB_GENERAL_SETTINGS'), 'nested-seventeen'); + +JHTML::_('joomconfig.start', 'page16'); + JHTML::_('joomconfig.row', 'jg_category_rss', 'text', 'COM_JOOMGALLERY_CONFIG_CV_CS_RSS', $this->_config->jg_category_rss); + $rssicon[] = JHTML::_('select.option', '0', JText::_('JNO')); + $rssicon[] = JHTML::_('select.option', 'atom', JText::_('COM_JOOMGALLERY_CONFIG_CV_CS_RSS_ICON_ATOM')); + $rssicon[] = JHTML::_('select.option', 'rss', JText::_('COM_JOOMGALLERY_CONFIG_CV_CS_RSS_ICON_RSS')); + $mc_jg_category_rss_icon = JHTML::_('select.genericlist', $rssicon, 'jg_category_rss_icon', 'class="inputbox" size="3"', 'value', 'text', $this->_config->jg_category_rss_icon); + JHTML::_('joomconfig.row', 'jg_category_rss_icon', 'custom', 'COM_JOOMGALLERY_CONFIG_CV_CS_RSS_ICON', $mc_jg_category_rss_icon); + JHTML::_('joomconfig.row', 'jg_uploadiconcategory', 'yesno', 'COM_JOOMGALLERY_CONFIG_COMMON_UPLOAD_ICON', $this->_config->get('jg_uploadiconcategory')); + JHTML::_('joomconfig.row', 'jg_showcathead', 'yesno', 'COM_JOOMGALLERY_CONFIG_CV_GS_CATEGORYTITLE', $this->_config->jg_showcathead); + JHTML::_('joomconfig.row', 'jg_usercatorder', 'yesno', 'COM_JOOMGALLERY_CONFIG_CV_GS_ORDERBY_USER', $this->_config->jg_usercatorder); + $arr_jg_usercatorderlist = explode(',', $this->_config->get('jg_usercatorderlist')); + $catorderlist[] = JHTML::_('select.option', 'date', JText::_('COM_JOOMGALLERY_CONFIG_CV_GS_USER_ORDERBY_DATE')); + $catorderlist[] = JHTML::_('select.option', 'user', JText::_('COM_JOOMGALLERY_CONFIG_CV_GS_USER_ORDERBY_AUTHOR')); + $catorderlist[] = JHTML::_('select.option', 'title', JText::_('COM_JOOMGALLERY_CONFIG_CV_GS_USER_ORDERBY_TITLE')); + $catorderlist[] = JHTML::_('select.option', 'hits', JText::_('COM_JOOMGALLERY_CONFIG_CV_GS_USER_ORDERBY_HITS')); + $catorderlist[] = JHTML::_('select.option', 'rating', JText::_('COM_JOOMGALLERY_CONFIG_CV_GS_USER_ORDERBY_RATING')); + $mc_jg_usercatorderlist = JHTML::_('select.genericlist', $catorderlist, 'jg_usercatorderlist[]', 'class="inputbox" size="5" multiple="multiple"', 'value', 'text', $arr_jg_usercatorderlist); + JHTML::_('joomconfig.row', 'jg_usercatorderlist', 'custom', 'COM_JOOMGALLERY_CONFIG_CV_GS_ORDERBY_LIST', $mc_jg_usercatorderlist); + JHTML::_('joomconfig.row', 'jg_showcatdescriptionincat', 'yesno', 'COM_JOOMGALLERY_CONFIG_CV_GS_CATDESCRIPTIONINCAT', $this->_config->jg_showcatdescriptionincat); + JHTML::_('joomconfig.row', 'jg_colnumb', 'text', 'COM_JOOMGALLERY_CONFIG_CV_GS_NUMB_COLUMN', $this->_config->jg_colnumb); + JHTML::_('joomconfig.row', 'jg_perpage', 'text', 'COM_JOOMGALLERY_CONFIG_CV_GS_IMGS_PER_PAGE', $this->_config->jg_perpage); + $catthumbalign[] = JHTML::_('select.option','1', JText::_('COM_JOOMGALLERY_COMMON_OPTION_FLUSH_LEFT')); + $catthumbalign[] = JHTML::_('select.option','3', JText::_('COM_JOOMGALLERY_COMMON_OPTION_CENTERED')); + $catthumbalign[] = JHTML::_('select.option','2', JText::_('COM_JOOMGALLERY_COMMON_OPTION_FLUSH_RIGHT')); + $mc_jg_catthumbalign = JHTML::_('select.genericlist', $catthumbalign, 'jg_catthumbalign', 'class="inputbox" size="3"', 'value', 'text', $this->_config->jg_catthumbalign); + JHTML::_('joomconfig.row', 'jg_catthumbalign', 'custom', 'COM_JOOMGALLERY_CONFIG_CV_GS_CATEGORY_THUMBALIGN', $mc_jg_catthumbalign); + $showpagenavi[] = JHTML::_('select.option','1', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_TOP_ONLY')); + $showpagenavi[] = JHTML::_('select.option','2', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_TOP_AND_BOTTOM')); + $showpagenavi[] = JHTML::_('select.option','3', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_BOTTOM_ONLY')); + $mc_jg_showpagenav = JHTML::_('select.genericlist', $showpagenavi, 'jg_showpagenav', 'class="inputbox" size="3"', 'value', 'text', $this->_config->jg_showpagenav); + JHTML::_('joomconfig.row', 'jg_showpagenav', 'custom', 'COM_JOOMGALLERY_CONFIG_COMMON_CATEGORY_PAGENAVIGATION', $mc_jg_showpagenav); + JHTML::_('joomconfig.row', 'jg_showpiccount', 'yesno', 'COM_JOOMGALLERY_CONFIG_CV_GS_NUMB_CATIMAGES', $this->_config->jg_showpiccount); + $mc_jg_detailpic_open = JHtml::_('joomselect.openimage', 'jg_detailpic_open', $this->_config->get('jg_detailpic_open')); + JHTML::_('joomconfig.row', 'jg_detailpic_open', 'custom', 'COM_JOOMGALLERY_CONFIG_CV_GS_OPEN_DETAIL_VIEW', $mc_jg_detailpic_open); + JHTML::_('joomconfig.row', 'jg_lightboxbigpic', 'yesno', 'COM_JOOMGALLERY_CONFIG_CV_GS_POPUP_ORIGINAL', $this->_config->jg_lightboxbigpic); + JHTML::_('joomconfig.row', 'jg_showtitle', 'yesno', 'COM_JOOMGALLERY_CONFIG_CV_GS_TITLE', $this->_config->jg_showtitle); + JHTML::_('joomconfig.row', 'jg_showpicasnew', 'yesno', 'COM_JOOMGALLERY_CONFIG_CV_GS_ASNEW', $this->_config->jg_showpicasnew); + JHTML::_('joomconfig.row', 'jg_daysnew', 'text', 'COM_JOOMGALLERY_CONFIG_CV_GS_DAYSNEW', $this->_config->jg_daysnew); + JHTML::_('joomconfig.row', 'jg_showhits', 'yesno', 'COM_JOOMGALLERY_CONFIG_CV_GS_HITS', $this->_config->jg_showhits); + JHTML::_('joomconfig.row', 'jg_showdownloads', 'yesno', 'COM_JOOMGALLERY_CONFIG_CV_GS_DOWNLOADS', $this->_config->jg_showdownloads); + JHTML::_('joomconfig.row', 'jg_showauthor', 'yesno', 'COM_JOOMGALLERY_CONFIG_CV_GS_AUTHOR', $this->_config->jg_showauthor); + JHTML::_('joomconfig.row', 'jg_showcatcom', 'yesno', 'COM_JOOMGALLERY_CONFIG_CV_GS_COMMENTS', $this->_config->jg_showcatcom); + JHTML::_('joomconfig.row', 'jg_showcatrate', 'yesno', 'COM_JOOMGALLERY_CONFIG_CV_GS_RATINGS', $this->_config->jg_showcatrate); + JHTML::_('joomconfig.row', 'jg_showcatdescription', 'yesno', 'COM_JOOMGALLERY_CONFIG_CV_GS_DESCRIPTION', $this->_config->jg_showcatdescription); + JHTML::_('joomconfig.row', 'jg_showcategorydownload', 'yesno', 'COM_JOOMGALLERY_CONFIG_COMMON_DOWNLOAD', $this->_config->jg_showcategorydownload); + JHTML::_('joomconfig.row', 'jg_showcategoryfavourite', 'yesno', 'COM_JOOMGALLERY_CONFIG_COMMON_FAVOURITES_LINK', $this->_config->jg_showcategoryfavourite); + JHTML::_('joomconfig.row', 'jg_category_report_images', 'yesno', 'COM_JOOMGALLERY_CONFIG_COMMON_REPORT_IMAGES', $this->_config->jg_category_report_images); + JHTML::_('joomconfig.row', 'jg_showcategoryeditorlinks', 'yesno', 'COM_JOOMGALLERY_CONFIG_COMMON_EDITOR_LINKS', $this->_config->jg_showcategoryeditorlinks); +JHTML::_('joomconfig.end'); + +// start Tab "Kategorie-Ansicht->Unterkategorien" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_CV_TAB_SUBCAT_SETTINGS'), 'nested-eighteen'); + +JHTML::_('joomconfig.start', 'page17'); + JHTML::_('joomconfig.row', 'jg_showsubcathead', 'yesno', 'COM_JOOMGALLERY_CONFIG_CV_SC_SUBCATEGORYHEADER', $this->_config->jg_showsubcathead); + JHTML::_('joomconfig.row', 'jg_showsubcatcount', 'yesno', 'COM_JOOMGALLERY_CONFIG_CV_SC_NUMB_SUBCATEGORIES', $this->_config->jg_showsubcatcount); + JHTML::_('joomconfig.row', 'jg_colsubcat', 'text', 'COM_JOOMGALLERY_CONFIG_CV_SC_NUMB_COLUMN', $this->_config->jg_colsubcat); + JHTML::_('joomconfig.row', 'jg_subperpage', 'text', 'COM_JOOMGALLERY_CONFIG_CV_SC_SUBCATS_PER_PAGE', $this->_config->jg_subperpage); + $showpagenavisubs[] = JHTML::_('select.option', '1', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_TOP_ONLY')); + $showpagenavisubs[] = JHTML::_('select.option', '2', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_TOP_AND_BOTTOM')); + $showpagenavisubs[] = JHTML::_('select.option', '3', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_BOTTOM_ONLY')); + $mc_jg_showpagenavsubs = JHTML::_('select.genericlist', $showpagenavisubs, 'jg_showpagenavsubs', 'class="inputbox" size="3"', 'value', 'text', $this->_config->jg_showpagenavsubs); + JHTML::_('joomconfig.row', 'jg_showpagenavsubs', 'custom', 'COM_JOOMGALLERY_CONFIG_COMMON_CATEGORY_PAGENAVIGATION', $mc_jg_showpagenavsubs); + $subthumbs[] = JHTML::_('select.option', '0', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_NONE')); + $subthumbs[] = JHTML::_('select.option', '1', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_MYCHOISE')); + $subthumbs[] = JHTML::_('select.option', '2', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_RANDOM')); + $subthumbs[] = JHTML::_('select.option', '3', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_OVERRIDE')); + $mc_jg_showsubthumbs = JHTML::_('select.genericlist', $subthumbs, 'jg_showsubthumbs', 'class="inputbox" size="4"', 'value', 'text', $this->_config->jg_showsubthumbs); + JHTML::_('joomconfig.row', 'jg_showsubthumbs', 'custom', 'COM_JOOMGALLERY_CONFIG_COMMON_CATEGORYTHUMBNAIL', $mc_jg_showsubthumbs); + $randomsubthumbs[] = JHTML::_('select.option', '1', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_FROM_PARENT_CAT_ONLY')); + $randomsubthumbs[] = JHTML::_('select.option', '2', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_FROM_CHILD_CAT_ONLY')); + $randomsubthumbs[] = JHTML::_('select.option', '3', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_FROM_BOTH')); + $mc_jg_showrandomsubthumb = JHTML::_('select.genericlist', $randomsubthumbs, 'jg_showrandomsubthumb', 'class="inputbox" size="3"', 'value', 'text', $this->_config->jg_showrandomsubthumb); + JHTML::_('joomconfig.row', 'jg_showrandomsubthumb', 'custom', 'COM_JOOMGALLERY_CONFIG_COMMON_RANDOMCATTHUMB', $mc_jg_showrandomsubthumb); + $subcatthumbalign[] = JHTML::_('select.option', '1', JText::_('COM_JOOMGALLERY_COMMON_OPTION_FLUSH_LEFT')); + $subcatthumbalign[] = JHTML::_('select.option', '3', JText::_('COM_JOOMGALLERY_COMMON_OPTION_CENTERED')); + $subcatthumbalign[] = JHTML::_('select.option', '2', JText::_('COM_JOOMGALLERY_COMMON_OPTION_FLUSH_RIGHT')); + $mc_jg_subcatthumbalign = JHTML::_('select.genericlist', $subcatthumbalign, 'jg_subcatthumbalign', 'class="inputbox" size="3"', 'value', 'text', $this->_config->jg_subcatthumbalign); + JHTML::_('joomconfig.row', 'jg_subcatthumbalign', 'custom', 'COM_JOOMGALLERY_CONFIG_COMMON_THUMBALIGN', $mc_jg_subcatthumbalign); + JHTML::_('joomconfig.row', 'jg_showdescriptionincategoryview', 'yesno', 'COM_JOOMGALLERY_CONFIG_CV_SC_DESCRIPTION', $this->_config->get('jg_showdescriptionincategoryview')); + JHTML::_('joomconfig.row', 'jg_ordersubcatbyalpha', 'yesno', 'COM_JOOMGALLERY_CONFIG_CV_SC_ORDER_BY_ALPHA', $this->_config->jg_ordersubcatbyalpha); + JHTML::_('joomconfig.row', 'jg_showtotalsubcatimages', 'yesno', 'COM_JOOMGALLERY_CONFIG_COMMON_CATEGORY_IMAGES', $this->_config->jg_showtotalsubcatimages); + JHTML::_('joomconfig.row', 'jg_showtotalsubcathits', 'yesno', 'COM_JOOMGALLERY_CONFIG_COMMON_CATEGORY_HITS', $this->_config->jg_showtotalsubcathits); + JHTML::_('joomconfig.row', 'jg_uploadiconsubcat', 'yesno', 'COM_JOOMGALLERY_CONFIG_COMMON_UPLOAD_ICON', $this->_config->get('jg_uploadiconsubcat')); +JHTML::_('joomconfig.end'); + +echo JHtml::_('tabs.end'); + +// start sixth nested MainTab "Detail-Ansicht" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_TAB_DETAIL_VIEW'), 'NestedMainPane6'); +// start sixth nested tabs pane +echo JHtml::_('tabs.start', 'NestedPaneSix', array('useCookie' => 1)); +// start Tab "Detail-Ansicht->Generelle Einstellungen" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_TAB_GENERAL_SETTINGS'), 'nested-nineteen'); + +JHTML::_('joomconfig.start', 'page18'); + JHTML::_('joomconfig.row', 'jg_showdetailpage', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_GS_ALLOW_DETAILPAGE', $this->_config->jg_showdetailpage); + JHTML::_('joomconfig.row', 'jg_disabledetailpage', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_GS_DISABLE_DEFAULT_DETAIL_VIEW', $this->_config->jg_disabledetailpage); + JHTML::_('joomconfig.row', 'jg_showdetailnumberofpics', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_GS_COUNTER', $this->_config->jg_showdetailnumberofpics); + JHTML::_('joomconfig.row', 'jg_cursor_navigation', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_GS_CURSOR_NAVIGATION', $this->_config->jg_cursor_navigation); + JHTML::_('joomconfig.row', 'jg_disable_rightclick_detail', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_GS_DISABLE_RIGHTCLICK', $this->_config->jg_disable_rightclick_detail); + JHTML::_('joomconfig.row', 'jg_detail_report_images', 'yesno', 'COM_JOOMGALLERY_CONFIG_COMMON_REPORT_IMAGES', $this->_config->jg_detail_report_images); + JHTML::_('joomconfig.row', 'jg_showdetaileditorlinks', 'yesno', 'COM_JOOMGALLERY_CONFIG_COMMON_EDITOR_LINKS', $this->_config->jg_showdetaileditorlinks); + $showdetailtitle[] = JHTML::_('select.option','0', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_NO_DISPLAY')); + $showdetailtitle[] = JHTML::_('select.option','1', JText::_('COM_JOOMGALLERY_CONFIG_DV_GS_OPTION_UPSIDE')); + $showdetailtitle[] = JHTML::_('select.option','2', JText::_('COM_JOOMGALLERY_CONFIG_DV_GS_OPTION_BELOW')); + $mc_jg_showdetailtitle = JHTML::_('select.genericlist', $showdetailtitle, 'jg_showdetailtitle', 'class="inputbox" size="3"', 'value', 'text', $this->_config->jg_showdetailtitle); + JHTML::_('joomconfig.row', 'jg_showdetailtitle', 'custom', 'COM_JOOMGALLERY_CONFIG_DV_GS_TITLE', $mc_jg_showdetailtitle); + JHTML::_('joomconfig.row', 'jg_showdetail', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_GS_INFORMATION', $this->_config->jg_showdetail); + JHTML::_('joomconfig.row', 'jg_showdetaildescription', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_GS_DESCRIPTION', $this->_config->jg_showdetaildescription); + JHTML::_('joomconfig.row', 'jg_showdetaildatum', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_GS_DATE', $this->_config->jg_showdetaildatum); + JHTML::_('joomconfig.row', 'jg_showdetailhits', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_GS_HITS', $this->_config->jg_showdetailhits); + JHTML::_('joomconfig.row', 'jg_showdetaildownloads', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_GS_DOWNLOADS', $this->_config->jg_showdetaildownloads); + JHTML::_('joomconfig.row', 'jg_showdetailrating', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_GS_RATING', $this->_config->jg_showdetailrating); + JHTML::_('joomconfig.row', 'jg_showdetailfilesize', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_GS_FILESIZE', $this->_config->jg_showdetailfilesize); + JHTML::_('joomconfig.row', 'jg_showdetailauthor', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_GS_AUTHOR', $this->_config->jg_showdetailauthor); + JHTML::_('joomconfig.row', 'jg_showoriginalfilesize', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_GS_ORIGFILESIZE', $this->_config->jg_showoriginalfilesize); + JHTML::_('joomconfig.row', 'jg_showdetaildownload', 'yesno', 'COM_JOOMGALLERY_CONFIG_COMMON_DOWNLOAD', $this->_config->jg_showdetaildownload); + JHTML::_('joomconfig.row', 'jg_watermark', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_GS_ADD_WATERMARK', $this->_config->jg_watermark); + $watermarkpos[] = JHTML::_('select.option', '1', JText::_('COM_JOOMGALLERY_CONFIG_DV_GS_OPTION_TOP_LEFT')); + $watermarkpos[] = JHTML::_('select.option', '2', JText::_('COM_JOOMGALLERY_CONFIG_DV_GS_OPTION_TOP_CENTER')); + $watermarkpos[] = JHTML::_('select.option', '3', JText::_('COM_JOOMGALLERY_CONFIG_DV_GS_OPTION_TOP_RIGHT')); + $watermarkpos[] = JHTML::_('select.option', '4', JText::_('COM_JOOMGALLERY_CONFIG_DV_GS_OPTION_MIDDLE_LEFT')); + $watermarkpos[] = JHTML::_('select.option', '5', JText::_('COM_JOOMGALLERY_CONFIG_DV_GS_OPTION_MIDDLE_CENTER')); + $watermarkpos[] = JHTML::_('select.option', '6', JText::_('COM_JOOMGALLERY_CONFIG_DV_GS_OPTION_MIDDLE_RIGHT')); + $watermarkpos[] = JHTML::_('select.option', '7', JText::_('COM_JOOMGALLERY_CONFIG_DV_GS_OPTION_BOTTOM_LEFT')); + $watermarkpos[] = JHTML::_('select.option', '8', JText::_('COM_JOOMGALLERY_CONFIG_DV_GS_OPTION_BOTTOM_CENTER')); + $watermarkpos[] = JHTML::_('select.option', '9', JText::_('COM_JOOMGALLERY_CONFIG_DV_GS_OPTION_BOTTOM_RIGHT')); + $mc_jg_watermarkpos = JHTML::_('select.genericlist', $watermarkpos, 'jg_watermarkpos', 'class="inputbox" size="1"', 'value', 'text', $this->_config->jg_watermarkpos); + JHTML::_('joomconfig.row', 'jg_watermarkpos', 'custom', 'COM_JOOMGALLERY_CONFIG_DV_GS_WATERMARK_POSITION', $mc_jg_watermarkpos); + $watermarkzoom[] = JHTML::_('select.option', '0', JText::_('COM_JOOMGALLERY_CONFIG_DV_GS_WATERMARKNORESIZE')); + $watermarkzoom[] = JHTML::_('select.option', '1', JText::_('COM_JOOMGALLERY_CONFIG_DV_GS_WATERMARKHEIGHT')); + $watermarkzoom[] = JHTML::_('select.option', '2', JText::_('COM_JOOMGALLERY_CONFIG_DV_GS_WATERMARKWIDTH')); + $mc_jg_watermarkzoom = JHTML::_('select.genericlist', $watermarkzoom, 'jg_watermarkzoom', 'class="inputbox" size="3"', 'value', 'text', $this->_config->jg_watermarkzoom); + JHTML::_('joomconfig.row', 'jg_watermarkzoom', 'custom', 'COM_JOOMGALLERY_CONFIG_DV_GS_WATERMARKZOOM', $mc_jg_watermarkzoom); + JHTML::_('joomconfig.row', 'jg_watermarksize', 'text', 'COM_JOOMGALLERY_CONFIG_DV_GS_WATERMARKSIZE', $this->_config->jg_watermarksize); + JHTML::_('joomconfig.row', 'jg_bigpic', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_GS_LINKTOORIGINAL', $this->_config->jg_bigpic); + JHTML::_('joomconfig.row', 'jg_bigpic_unreg', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_GS_LINKTOORIGINAL_UNREG', $this->_config->jg_bigpic_unreg); + $mc_jg_bigpic_open = JHtml::_('joomselect.openimage', 'jg_bigpic_open', $this->_config->get('jg_bigpic_open'), false); + JHTML::_('joomconfig.row', 'jg_bigpic_open', 'custom', 'COM_JOOMGALLERY_CONFIG_DV_GS_OPEN_ORIGINAL', $mc_jg_bigpic_open); + $bbcodelinks[] = JHTML::_('select.option','0', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_NO_DISPLAY')); + $bbcodelinks[] = JHTML::_('select.option','1', JText::_('COM_JOOMGALLERY_CONFIG_DV_GS_BBCODE_IMG_ONLY')); + $bbcodelinks[] = JHTML::_('select.option','2', JText::_('COM_JOOMGALLERY_CONFIG_DV_GS_BBCODE_URL_ONLY')); + $bbcodelinks[] = JHTML::_('select.option','3', JText::_('COM_JOOMGALLERY_CONFIG_DV_GS_BBCODE_BOTH')); + $mc_jg_bbcodelinks = JHTML::_('select.genericlist', $bbcodelinks, 'jg_bbcodelink', 'class="inputbox" size="4"', 'value', 'text',$this->_config->jg_bbcodelink); + JHTML::_('joomconfig.row', 'jg_bbcodelink', 'custom', 'COM_JOOMGALLERY_CONFIG_DV_GS_BBCODELINK', $mc_jg_bbcodelinks); + JHTML::_('joomconfig.row', 'jg_showcommentsunreg', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_GS_COMMENTS_REG', $this->_config->jg_showcommentsunreg, $this->display); + $showcommentsarea[] = JHTML::_('select.option', '1', JText::_('COM_JOOMGALLERY_CONFIG_DV_GS_OPTION_ABOVE_COMMENTS')); + $showcommentsarea[] = JHTML::_('select.option', '2', JText::_('COM_JOOMGALLERY_CONFIG_DV_GS_OPTION_UNDERNEATH_COMMENTS')); + $mc_jg_showcommentsarea = JHTML::_('select.genericlist', $showcommentsarea, 'jg_showcommentsarea', 'class="inputbox" size="2"', 'value', 'text', $this->_config->jg_showcommentsarea); + JHTML::_('joomconfig.row', 'jg_showcommentsarea', 'custom', 'COM_JOOMGALLERY_CONFIG_DV_GS_COMMENTSAREA', $mc_jg_showcommentsarea); + JHTML::_('joomconfig.row', 'jg_send2friend', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_GS_SEND2FRIEND', $this->_config->jg_send2friend); +JHTML::_('joomconfig.end'); + +// start Tab "Detail-Ansicht->Accordion" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_DV_TAB_ACCORDION_SETTINGS'), 'nested-twenty'); +JHTML::_('joomconfig.start', 'dtlaccordion'); + JHTML::_('joomconfig.row', 'jg_showdetailaccordion', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_AC_ACCORDION', $this->_config->jg_showdetailaccordion); + JHTML::_('joomconfig.row', 'jg_accordionduration', 'text', 'COM_JOOMGALLERY_CONFIG_DV_AC_DURATION', $this->_config->jg_accordionduration); + JHTML::_('joomconfig.row', 'jg_accordiondisplay', 'text', 'COM_JOOMGALLERY_CONFIG_DV_AC_DISPLAY', $this->_config->jg_accordiondisplay); + JHTML::_('joomconfig.row', 'jg_accordioninitialeffect', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_AC_INITIALEFFECT', $this->_config->jg_accordioninitialeffect); + JHTML::_('joomconfig.row', 'jg_accordionopacity', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_AC_OPACITY', $this->_config->jg_accordionopacity); + JHTML::_('joomconfig.row', 'jg_accordionalwayshide', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_AC_ALWAYSHIDE', $this->_config->jg_accordionalwayshide); +JHTML::_('joomconfig.end'); + +// start Tab "Detail-Ansicht->Motiongallery" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_DV_TAB_MOTIONGALLERY_SETTINGS'), 'nested-twentyone'); + +JHTML::_('joomconfig.start', 'page19'); + JHTML::_('joomconfig.row', 'jg_minis', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_MG_MOTIONGALLERY', $this->_config->jg_minis); + $joom_ShowMotionMinis[] = JHTML::_('select.option', '1', JText::_('COM_JOOMGALLERY_CONFIG_DV_MG_OPTION_STATIC')); + $joom_ShowMotionMinis[] = JHTML::_('select.option', '2', JText::_('COM_JOOMGALLERY_CONFIG_DV_MG_OPTION_MOVEABLE')); + $mc_jg_motionminis = JHTML::_('select.genericlist', $joom_ShowMotionMinis, 'jg_motionminis', 'class="inputbox" size="2"', 'value', 'text', $this->_config->jg_motionminis); + JHTML::_('joomconfig.row', 'jg_motionminis', 'custom', 'COM_JOOMGALLERY_CONFIG_DV_MG_DISPLAYMODE', $mc_jg_motionminis); + JHTML::_('joomconfig.row', 'jg_motionminiWidth', 'text', 'COM_JOOMGALLERY_CONFIG_DV_MG_WIDTH', $this->_config->jg_motionminiWidth); + JHTML::_('joomconfig.row', 'jg_motionminiLimit', 'text', 'COM_JOOMGALLERY_CONFIG_DV_MG_LIMIT', $this->_config->jg_motionminiLimit); + JHTML::_('joomconfig.row', 'jg_motionminiHeight', 'text', 'COM_JOOMGALLERY_CONFIG_DV_MG_HEIGHT', $this->_config->jg_motionminiHeight); + JHTML::_('joomconfig.row', 'jg_miniWidth', 'text', 'COM_JOOMGALLERY_CONFIG_DV_MG_MINIS_MAXWIDTH', $this->_config->jg_miniWidth); + JHTML::_('joomconfig.row', 'jg_miniHeight', 'text', 'COM_JOOMGALLERY_CONFIG_DV_MG_MINIS_MAXHEIGHT', $this->_config->jg_miniHeight); + $joom_minisprop[] = JHTML::_('select.option','0', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_SAMEWIDTHANDHEIGHT')); + $joom_minisprop[] = JHTML::_('select.option','1', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_SAMEWIDTH')); + $joom_minisprop[] = JHTML::_('select.option','2', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_SAMEHIGHT')); + $mc_jg_minisprop = JHTML::_('select.genericlist', $joom_minisprop, 'jg_minisprop', 'class="inputbox" size="3"', 'value', 'text', $this->_config->jg_minisprop); + JHTML::_('joomconfig.row', 'jg_minisprop', 'custom', 'COM_JOOMGALLERY_CONFIG_DV_MG_MINIS_PROPORTIONS', $mc_jg_minisprop); +JHTML::_('joomconfig.end'); + +// start Tab "Detail-Ansicht->Namensschilder" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_DV_TAB_NAMETAGS_SETTINGS'), 'nested-twentytwo'); + +JHTML::_('joomconfig.start', 'page20'); + JHTML::_('joomconfig.row', 'jg_nameshields', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_NT_NAMETAGS', $this->_config->jg_nameshields); + JHTML::_('joomconfig.row', 'jg_nameshields_others', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_NT_OTHERS', $this->_config->jg_nameshields_others); + JHTML::_('joomconfig.row', 'jg_nameshields_unreg', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_NT_GUEST_VISIBLE', $this->_config->jg_nameshields_unreg, $this->display); + JHTML::_('joomconfig.row', 'jg_show_nameshields_unreg', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_NT_GUEST_INFORMATION', $this->_config->jg_show_nameshields_unreg, $this->display); + JHTML::_('joomconfig.row', 'jg_nameshields_height', 'text', 'COM_JOOMGALLERY_CONFIG_DV_NT_HEIGHT', $this->_config->jg_nameshields_height); + JHTML::_('joomconfig.row', 'jg_nameshields_width', 'text', 'COM_JOOMGALLERY_CONFIG_DV_NT_WIDTH', $this->_config->jg_nameshields_width); +JHTML::_('joomconfig.end'); + +// start Tab "Detail-Ansicht->Slideshow" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_DV_TAB_SLIDESHOW_SETTINGS'), 'nested-twentythree'); + +JHTML::_('joomconfig.start', 'page21'); + JHTML::_('joomconfig.row', 'jg_slideshow', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_SL_SLIDESHOW', $this->_config->jg_slideshow); + JHTML::_('joomconfig.row', 'jg_slideshow_timer', 'text', 'COM_JOOMGALLERY_CONFIG_DV_SL_TIMEFRAME', $this->_config->jg_slideshow_timer); + $joom_transitions[] = JHTML::_('select.option','0', 'fade'); + $joom_transitions[] = JHTML::_('select.option','1', 'fadeslideleft'); + $joom_transitions[] = JHTML::_('select.option','2', 'crossfade'); + $joom_transitions[] = JHTML::_('select.option','3', 'continuoushorizontal'); + $joom_transitions[] = JHTML::_('select.option','4', 'continuousvertical'); + $joom_transitions[] = JHTML::_('select.option','5', 'fadebg'); + $mc_jg_transitions = JHTML::_('select.genericlist', $joom_transitions, 'jg_slideshow_transition', 'class="inputbox" size="6"', 'value', 'text', $this->_config->jg_slideshow_transition); + JHTML::_('joomconfig.row', 'jg_slideshow_transition', 'custom', 'COM_JOOMGALLERY_CONFIG_DV_SL_TRANSITION', $mc_jg_transitions); + JHTML::_('joomconfig.row', 'jg_slideshow_transtime', 'text', 'COM_JOOMGALLERY_CONFIG_DV_SL_TRANSITION_TIME', $this->_config->jg_slideshow_transtime); + JHTML::_('joomconfig.row', 'jg_slideshow_maxdimauto', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_SL_MAXDIMAUTO', $this->_config->jg_slideshow_maxdimauto); + JHTML::_('joomconfig.row', 'jg_slideshow_width', 'text', 'COM_JOOMGALLERY_CONFIG_DV_SL_WIDTH', $this->_config->jg_slideshow_width); + JHTML::_('joomconfig.row', 'jg_slideshow_heigth', 'text', 'COM_JOOMGALLERY_CONFIG_DV_SL_HEIGHT', $this->_config->jg_slideshow_heigth); + JHTML::_('joomconfig.row', 'jg_slideshow_infopane', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_SL_INFOPANE', $this->_config->jg_slideshow_infopane); + JHTML::_('joomconfig.row', 'jg_slideshow_carousel', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_SL_CAROUSEL', $this->_config->jg_slideshow_carousel); + JHTML::_('joomconfig.row', 'jg_slideshow_arrows', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_SL_ARROWS', $this->_config->jg_slideshow_arrows); + $joom_repetitions[] = JHTML::_('select.option','0', JText::_('COM_JOOMGALLERY_CONFIG_DV_SL_REPEAT_ENDLESS')); + $joom_repetitions[] = JHTML::_('select.option','1', JText::_('COM_JOOMGALLERY_CONFIG_DV_SL_REPEAT_ASK')); + $joom_repetitions[] = JHTML::_('select.option','2', JText::_('COM_JOOMGALLERY_CONFIG_DV_SL_REPEAT_STOP')); + $mc_jg_repetitions = JHTML::_('select.genericlist', $joom_repetitions, 'jg_slideshow_repeat', 'class="inputbox" size="3"', 'value', 'text', $this->_config->jg_slideshow_repeat); + JHTML::_('joomconfig.row', 'jg_slideshow_repeat', 'custom', 'COM_JOOMGALLERY_CONFIG_DV_SL_REPETITION', $mc_jg_repetitions); +JHTML::_('joomconfig.end'); + +// start Tab "Detail-Ansicht->Exif-Daten" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_DV_TAB_EXIF_SETTINGS'), 'nested-twentyfour'); + +JHTML::_('joomconfig.start', 'page22'); + JHTML::_('joomconfig.intro', JText::_('COM_JOOMGALLERY_CONFIG_DV_ED_EXIF_INTRO_ONE').'
    '.JText::_('COM_JOOMGALLERY_CONFIG_DV_ED_EXIF_INTRO_TWO').'
    '.$this->exifmsg); + JHTML::_('joomconfig.row', 'jg_showexifdata', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_ED_EXIFDATA', $this->_config->jg_showexifdata); + JHTML::_('joomconfig.row', 'jg_showgeotagging', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_ED_SHOWGEOTAGGING', $this->_config->jg_showgeotagging); + JHTML::_('joomconfig.row', 'jg_geotaggingkey', 'text', 'COM_JOOMGALLERY_CONFIG_DV_ED_GEOTAGGINGKEY', $this->_config->jg_geotaggingkey); +?> + + +exif_definitions); $ii++): + $tags = count($this->exif_config_array[$this->exif_definitions[$ii]['TAG']]); + $jgtags = $this->exif_definitions[$ii]['JG']; + $tagname = $this->exif_definitions[$ii]['NAME']; + $header = $this->exif_definitions[$ii]['HEAD']; ?> + + + + + + + + + + + +exif_config_array[$this->exif_definitions[$ii]['TAG']] as $key => $value): + $checked = ''; + if((in_array($key, $jgtags)) && $jgtags[0]): + $checked = ' checked="checked"'; + endif; ?> + + + + + + + + + + + +IPTC-Daten" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_DV_TAB_IPTC_SETTINGS'), 'nested-twentyfive'); + +JHTML::_('joomconfig.start', 'page23'); + JHTML::_('joomconfig.intro', JText::_('COM_JOOMGALLERY_CONFIG_DV_ID_IPTC_INTRO_ONE').'
    '.JText::_('COM_JOOMGALLERY_CONFIG_DV_ID_IPTC_INTRO_TWO')); + JHTML::_('joomconfig.row', 'jg_showiptcdata', 'yesno', 'COM_JOOMGALLERY_CONFIG_DV_ID_IPTCDATA', $this->_config->jg_showiptcdata); +?> +
    + +
    +   + + + + + + + + +
    + /> + + + + + + + + +
    +   +
    + +iptc_definitions); $ii++): + $tags = count($this->iptc_config_array[$this->iptc_definitions[$ii]['TAG']]); + $jgtags = $this->iptc_definitions[$ii]['JG']; + $tagname = $this->iptc_definitions[$ii]['NAME']; + $header = $this->iptc_definitions[$ii]['HEAD']; ?> + + + + + + + + + + + +iptc_config_array[$this->iptc_definitions[$ii]['TAG']] as $key => $value): + $checked = ''; + if((in_array($key, $jgtags)) && $jgtags[0]): + $checked = ' checked="checked"'; + endif; ?> + + + + + + + + + + + + +
    + +
    +   + + + + + + + + +
    + /> + + + + + + + + +
    +   +
    + +'.JText::_('COM_JOOMGALLERY_CONFIG_DV_ID_COPYRIGHT_LANGUAGE')); +JHTML::_('joomconfig.end'); + +echo JHtml::_('tabs.end'); + +// start seventh nested MainTab "Toplisten" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_TAB_TOPLIST_SETTINGS'), 'NestedMainPane7'); +// start seventh nested tabs pane +echo JHtml::_('tabs.start', 'NestedPaneSeven', array('useCookie' => 1)); +// start Tab "Toplisten->Generelle Einstellungen" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_TAB_GENERAL_SETTINGS'), 'nested-twentysix'); + +JHTML::_('joomconfig.start', 'page24'); + $toplist[] = JHTML::_('select.option','0', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_NO_DISPLAY')); + $toplist[] = JHTML::_('select.option','1', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_IN_HEADER')); + $toplist[] = JHTML::_('select.option','2', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_IN_HEADERFOOTER')); + $toplist[] = JHTML::_('select.option','3', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_IN_FOOTER')); + $mc_jg_showtoplist = JHTML::_('select.genericlist',$toplist, 'jg_showtoplist', 'class="inputbox" size="4"', 'value', 'text', $this->_config->jg_showtoplist); + JHTML::_('joomconfig.row', 'jg_showtoplist', 'custom', 'COM_JOOMGALLERY_CONFIG_TL_GS_TOPLIST', $mc_jg_showtoplist); + $wheretoplist[] = JHTML::_('select.option','0', JText::_('COM_JOOMGALLERY_CONFIG_TL_GS_OPTION_ALL_VIEWS')); + $wheretoplist[] = JHTML::_('select.option','1', JText::_('COM_JOOMGALLERY_CONFIG_TL_GS_OPTION_ONLY_GALLERYVIEW')); + $wheretoplist[] = JHTML::_('select.option','2', JText::_('COM_JOOMGALLERY_CONFIG_TL_GS_OPTION_GALLERY_AND_CATEGORYVIEW')); + $mc_jg_whereshowtoplist = JHTML::_('select.genericlist', $wheretoplist, 'jg_whereshowtoplist', 'class="inputbox" size="3"', 'value', 'text', $this->_config->jg_whereshowtoplist); + JHTML::_('joomconfig.row', 'jg_whereshowtoplist', 'custom', 'COM_JOOMGALLERY_CONFIG_TL_GS_ON_VIEWS', $mc_jg_whereshowtoplist); + JHTML::_('joomconfig.row', 'jg_toplistcols', 'text', 'COM_JOOMGALLERY_CONFIG_TL_GS_NUMB_COLUMN', $this->_config->jg_toplistcols); + JHTML::_('joomconfig.row', 'jg_toplist', 'text', 'COM_JOOMGALLERY_CONFIG_TL_GS_NUMB_ENTRIES', $this->_config->jg_toplist); + $topthumbalign[] = JHTML::_('select.option', '1', JText::_('COM_JOOMGALLERY_COMMON_OPTION_FLUSH_LEFT')); + $topthumbalign[] = JHTML::_('select.option', '3', JText::_('COM_JOOMGALLERY_COMMON_OPTION_CENTERED')); + $topthumbalign[] = JHTML::_('select.option', '2', JText::_('COM_JOOMGALLERY_COMMON_OPTION_FLUSH_RIGHT')); + $mc_jg_topthumbalign = JHTML::_('select.genericlist', $topthumbalign, 'jg_topthumbalign', 'class="inputbox" size="3"', 'value', 'text', $this->_config->jg_topthumbalign ); + JHTML::_('joomconfig.row', 'jg_topthumbalign', 'custom', 'COM_JOOMGALLERY_CONFIG_TL_GS_THUMBALIGN', $mc_jg_topthumbalign); + $toptextalign[] = JHTML::_('select.option', '1', JText::_('COM_JOOMGALLERY_COMMON_OPTION_FLUSH_LEFT')); + $toptextalign[] = JHTML::_('select.option', '3', JText::_('COM_JOOMGALLERY_COMMON_OPTION_CENTERED')); + $toptextalign[] = JHTML::_('select.option', '2', JText::_('COM_JOOMGALLERY_COMMON_OPTION_FLUSH_RIGHT')); + $mc_jg_toptextalign = JHTML::_('select.genericlist', $toptextalign, 'jg_toptextalign', 'class="inputbox" size="3"', 'value', 'text', $this->_config->jg_toptextalign ); + JHTML::_('joomconfig.row', 'jg_toptextalign', 'custom', 'COM_JOOMGALLERY_CONFIG_TL_GS_TEXTALIGN', $mc_jg_toptextalign); + JHTML::_('joomconfig.row', 'jg_showrate', 'yesno', 'COM_JOOMGALLERY_CONFIG_TL_GS_RATING', $this->_config->jg_showrate); + JHTML::_('joomconfig.row', 'jg_showlatest', 'yesno', 'COM_JOOMGALLERY_CONFIG_TL_GS_LATEST', $this->_config->jg_showlatest); + JHTML::_('joomconfig.row', 'jg_showcom', 'yesno', 'COM_JOOMGALLERY_CONFIG_TL_GS_COMMENTS', $this->_config->jg_showcom); + JHTML::_('joomconfig.row', 'jg_showthiscomment', 'yesno', 'COM_JOOMGALLERY_CONFIG_TL_GS_THISCOMMENT', $this->_config->jg_showthiscomment); + JHTML::_('joomconfig.row', 'jg_showmostviewed', 'yesno', 'COM_JOOMGALLERY_CONFIG_TL_GS_MOSTVIEWED', $this->_config->jg_showmostviewed); + JHTML::_('joomconfig.row', 'jg_showtoplistdownload', 'yesno', 'COM_JOOMGALLERY_CONFIG_COMMON_DOWNLOAD', $this->_config->jg_showtoplistdownload); + JHTML::_('joomconfig.row', 'jg_showtoplistfavourite', 'yesno', 'COM_JOOMGALLERY_CONFIG_COMMON_FAVOURITES_LINK', $this->_config->jg_showtoplistfavourite); + JHTML::_('joomconfig.row', 'jg_toplist_report_images', 'yesno', 'COM_JOOMGALLERY_CONFIG_COMMON_REPORT_IMAGES', $this->_config->jg_toplist_report_images); + JHTML::_('joomconfig.row', 'jg_showtoplisteditorlinks', 'yesno', 'COM_JOOMGALLERY_CONFIG_COMMON_EDITOR_LINKS', $this->_config->jg_showtoplisteditorlinks); +JHTML::_('joomconfig.end'); + +echo JHtml::_('tabs.end'); + +// start eighth nested MainTab "Favoriten" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_TAB_FAVOURITES_SETTINGS'), 'NestedMainPane8'); +// start eighth nested tabs pane +echo JHtml::_('tabs.start', 'NestedPaneEight', array('useCookie' => 1)); +// start Tab "Favoriten->Generelle Einstellungen" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_TAB_GENERAL_SETTINGS'), 'nested-twentyseven'); + +JHTML::_('joomconfig.start', 'page25'); + JHTML::_('joomconfig.row', 'jg_favourites', 'yesno', 'COM_JOOMGALLERY_CONFIG_FV_GS_FAVOURITES', $this->_config->jg_favourites); + JHTML::_('joomconfig.row', 'jg_favouritesshownotauth', 'yesno', 'COM_JOOMGALLERY_CONFIG_FV_GS_GUEST_INFORMATION', $this->_config->jg_favouritesshownotauth); + JHTML::_('joomconfig.row', 'jg_maxfavourites', 'text', 'COM_JOOMGALLERY_CONFIG_FV_GS_MAX_IMAGES', $this->_config->jg_maxfavourites); + JHTML::_('joomconfig.row', 'jg_zipdownload', 'yesno', 'COM_JOOMGALLERY_CONFIG_FV_GS_ZIPDOWNLOAD', $this->_config->jg_zipdownload); + JHTML::_('joomconfig.row', 'jg_usefavouritesforpubliczip', 'yesno', 'COM_JOOMGALLERY_CONFIG_FV_GS_FOR_PUBLIC_ZIP', $this->_config->jg_usefavouritesforpubliczip); + JHTML::_('joomconfig.row', 'jg_usefavouritesforzip', 'yesno', 'COM_JOOMGALLERY_CONFIG_FV_GS_FOR_ZIP', $this->_config->jg_usefavouritesforzip); + JHTML::_('joomconfig.row', 'jg_allimagesofcategory', 'yesno', 'COM_JOOMGALLERY_CONFIG_FV_GS_ALL_IMAGES_OF_CATEGORY', $this->_config->jg_allimagesofcategory); + JHTML::_('joomconfig.row', 'jg_showfavouritesdownload', 'yesno', 'COM_JOOMGALLERY_CONFIG_COMMON_DOWNLOAD', $this->_config->jg_showfavouritesdownload); + JHTML::_('joomconfig.row', 'jg_showfavouriteseditorlinks', 'yesno', 'COM_JOOMGALLERY_CONFIG_COMMON_EDITOR_LINKS', $this->_config->jg_showfavouriteseditorlinks); +JHTML::_('joomconfig.end'); + +echo JHtml::_('tabs.end'); + +// start nineth nested MainTab "Search" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_TAB_SEARCH_SETTINGS'), 'NestedMainPane9'); +// start nineth nested tabs pane +echo JHtml::_('tabs.start', 'NestedPaneNine', array('useCookie' => 1)); +// start Tab "Search->General settings" +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_TAB_GENERAL_SETTINGS'), 'nested-twentyeight'); + +JHTML::_('joomconfig.start', 'page28'); + $search[] = JHTML::_('select.option','0', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_NO_DISPLAY')); + $search[] = JHTML::_('select.option','1', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_IN_HEADER')); + $search[] = JHTML::_('select.option','2', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_IN_FOOTER')); + $search[] = JHTML::_('select.option','3', JText::_('COM_JOOMGALLERY_CONFIG_COMMON_OPTION_IN_HEADERFOOTER')); + $mc_jg_search = JHTML::_('select.genericlist', $search, 'jg_search', 'class="inputbox" size="4"', 'value', 'text', $this->_config->jg_search); + JHTML::_('joomconfig.row', 'jg_search', 'custom', 'COM_JOOMGALLERY_CONFIG_SS_GS_SEARCHFIELD', $mc_jg_search); + JHTML::_('joomconfig.row', 'jg_searchcols', 'text', 'COM_JOOMGALLERY_CONFIG_SS_GS_NUMB_COLUMN', $this->_config->jg_searchcols); + $searchthumbalign[] = JHTML::_('select.option', '1', JText::_('COM_JOOMGALLERY_COMMON_OPTION_FLUSH_LEFT')); + $searchthumbalign[] = JHTML::_('select.option', '3', JText::_('COM_JOOMGALLERY_COMMON_OPTION_CENTERED')); + $searchthumbalign[] = JHTML::_('select.option', '2', JText::_('COM_JOOMGALLERY_COMMON_OPTION_FLUSH_RIGHT')); + $mc_jg_searchthumbalign = JHTML::_('select.genericlist', $searchthumbalign, 'jg_searchthumbalign', 'class="inputbox" size="3"', 'value', 'text', $this->_config->jg_searchthumbalign ); + JHTML::_('joomconfig.row', 'jg_searchthumbalign', 'custom', 'COM_JOOMGALLERY_CONFIG_SS_GS_THUMBALIGN', $mc_jg_searchthumbalign); + $searchtextalign[] = JHTML::_('select.option', '1', JText::_('COM_JOOMGALLERY_COMMON_OPTION_FLUSH_LEFT')); + $searchtextalign[] = JHTML::_('select.option', '3', JText::_('COM_JOOMGALLERY_COMMON_OPTION_CENTERED')); + $searchtextalign[] = JHTML::_('select.option', '2', JText::_('COM_JOOMGALLERY_COMMON_OPTION_FLUSH_RIGHT')); + $mc_jg_searchtextalign = JHTML::_('select.genericlist', $searchtextalign, 'jg_searchtextalign', 'class="inputbox" size="3"', 'value', 'text', $this->_config->jg_searchtextalign ); + JHTML::_('joomconfig.row', 'jg_searchtextalign', 'custom', 'COM_JOOMGALLERY_CONFIG_SS_GS_TEXTALIGN', $mc_jg_searchtextalign); + JHTML::_('joomconfig.row', 'jg_showsearchdownload', 'yesno', 'COM_JOOMGALLERY_CONFIG_COMMON_DOWNLOAD', $this->_config->jg_showsearchdownload); + JHTML::_('joomconfig.row', 'jg_showsearchfavourite', 'yesno', 'COM_JOOMGALLERY_CONFIG_COMMON_FAVOURITES_LINK', $this->_config->jg_showsearchfavourite); + JHTML::_('joomconfig.row', 'jg_search_report_images', 'yesno', 'COM_JOOMGALLERY_CONFIG_COMMON_REPORT_IMAGES', $this->_config->jg_search_report_images); + JHTML::_('joomconfig.row', 'jg_showsearcheditorlinks', 'yesno', 'COM_JOOMGALLERY_CONFIG_COMMON_EDITOR_LINKS', $this->_config->jg_showsearcheditorlinks); + JHTML::_('joomconfig.end'); + +echo JHtml::_('tabs.end'); + +echo JHtml::_('tabs.end'); + +?> + + + + +_config->isExtended()): ?> + + + + + + + diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/config/tmpl/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/config/tmpl/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/config/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/config/view.html.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/config/view.html.php new file mode 100644 index 00000000..b51dbb8a --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/config/view.html.php @@ -0,0 +1,464 @@ +load(_JOOM_OPTION.'.exif', JPATH_SITE); + $language->load(_JOOM_OPTION.'.iptc', JPATH_SITE); + + $display = true; + if($this->_config->isExtended()) + { + $config_id = JRequest::getInt('id'); + + // Overwrite config object with specified one + $this->_config = JoomConfig::getInstance($config_id); + + if(JRequest::getInt('group_id') || ($config_id && $config_id != 1)) + { + $display = false; + } + } + + // Check the installation of GD + $gdver = $this->get('GDVersion'); + // Returns version, 0 if not installed, or -1 if appears + // to be installed but not verified + if($gdver > 0) + { + $gdmsg = JText::sprintf('COM_JOOMGALLERY_CONFIG_GS_IP_GDLIB_INSTALLED', $gdver); + } + else + { + if($gdver == -1) + { + $gdmsg = JText::_('COM_JOOMGALLERY_CONFIG_GS_IP_GDLIB_NO_VERSION'); + } + else + { + $gdmsg = JText::_('COM_JOOMGALLERY_CONFIG_GS_IP_GDLIB_NOT_INSTALLED') . + 'http://www.php.net/gd' + . JText::_('COM_JOOMGALLERY_GD_MORE_INFO'); + } + } + // Check the installation of ImageMagick + // first check if exec() has been diabled in php.ini + if($this->get('DisabledExec')) + { + $immsg = JText::_('COM_JOOMGALLERY_CONFIG_GS_IP_IMAGIC_EXEC_DISABLED'); + } + else + { + $imver = $this->get('IMVersion'); + // Returns version, 0 if not installed or path not properly configured + if($imver) + { + $immsg = JText::_('COM_JOOMGALLERY_CONFIG_GS_IP_IMAGIC_INSTALLED') . $imver; + // Add the information that IM was detected automatically if path is empty + if(!$this->_config->get('jg_impath')) + { + $immsg .= JText::_('COM_JOOMGALLERY_CONFIG_GS_IP_IMAGIC_INSTALLED_AUTO') ; + } + } + else + { + $immsg = JText::_('COM_JOOMGALLERY_CONFIG_GS_IP_IMAGIC_NOT_INSTALLED'); + } + } + + // Check the installation of Exif + $exifmsg = ''; + if(!extension_loaded('exif')) + { + $exifmsg = '
    [' . JText::_('COM_JOOMGALLERY_CONFIG_DV_ED_NOT_INSTALLED') . ' ' . JText::_('COM_JOOMGALLERY_CONFIG_DV_ED_NO_OPTIONS') . ']
    '; + } + else + { + $exifmsg = '
    [' . JText::_('COM_JOOMGALLERY_CONFIG_DV_ED_INSTALLED') . ']
    '; + if(!function_exists('exif_read_data')) + { + $exifmsg = '
    [' . JText::_('COM_JOOMGALLERY_CONFIG_DV_ED_INSTALLED_BUT') . ' ' . JText::_('COM_JOOMGALLERY_CONFIG_DV_ED_NO_OPTIONS') . ']
    '; + } + } + + // Check pathes and watermark file + $writeable = '' + . JText::_('COM_JOOMGALLERY_CONFIG_GS_PD_DIRECTORY_WRITEABLE') . + ''; + $unwriteable = '' + . JText::_('COM_JOOMGALLERY_CONFIG_GS_PD_DIRECTORY_UNWRITEABLE') . + ''; + + if(is_writeable($this->getPath('img'))) + { + $write_pathimages = $writeable; + } + else + { + $write_pathimages = $unwriteable; + } + if(is_writeable($this->getPath('orig'))) + { + $write_pathoriginalimages = $writeable; + } + else + { + $write_pathoriginalimages = $unwriteable; + } + if(is_writeable($this->getPath('thumb'))) + { + $write_paththumbs = $writeable; + } + else + { + $write_paththumbs = $unwriteable; + } + if(is_writeable($this->getPath('ftp'))) + { + $write_pathftpupload = $writeable; + } + else + { + $write_pathftpupload = $unwriteable; + } + if(is_writeable($this->getPath('temp'))) + { + $write_pathtemp = $writeable; + } + else + { + $write_pathtemp = $unwriteable; + } + if(is_writeable($this->getPath('wtm'))) + { + $write_pathwm = $writeable; + } + else + { + $write_pathwm = $unwriteable; + } + if(is_file($this->getPath('wtm').'/'.$this->_config->get('jg_wmfile'))) + { + $wmfilemsg = '' + . JText::_('COM_JOOMGALLERY_CONFIG_GS_PD_FILE_EXIST') . + ''; + } + else + { + $wmfilemsg = '' + . JText::_('COM_JOOMGALLERY_CONFIG_GS_PD_FILE_NOT_EXIST') . + ''; + } + + // Check whether CSS file (joom_settings.css) is writeable + if(is_writeable(JPATH_ROOT.'/media/joomgallery/css/'.$this->_config->getStyleSheetName())) + { + $cssfilemsg = '
    ['.JText::_('COM_JOOMGALLERY_CONFIG_GS_PD_CSS_CONFIGURATION_WRITEABLE').']
    '; + } + else + { + $cssfilemsg = '
    ['.JText::_('COM_JOOMGALLERY_CONFIG_GS_PD_CSS_CONFIGURATION_NOT_WRITEABLE').' '.JText::_('COM_JOOMGALLERY_COMMON_CHECK_PERMISSIONS').']
    '; + } + + // Exif + require_once JPATH_COMPONENT.'/includes/exifarray.php'; + + $ifdotags = explode(',', $this->_config->get('jg_ifdotags')); + $subifdtags = explode(',', $this->_config->get('jg_subifdtags')); + $gpstags = explode(',', $this->_config->get('jg_gpstags')); + + $exif_definitions = array( + 1 => array ('TAG' => 'IFD0', 'JG' => $ifdotags, 'NAME' => 'jg_ifdotags[]', 'HEAD' => JText::_('COM_JOOMGALLERY_IFD0TAGS')), + 2 => array ('TAG' => 'EXIF', 'JG' => $subifdtags, 'NAME' => 'jg_subifdtags[]', 'HEAD' => JText::_('COM_JOOMGALLERY_SUBIFDTAGS')), + 3 => array ('TAG' => 'GPS', 'JG' => $gpstags, 'NAME' => 'jg_gpstags[]', 'HEAD' => JText::_('COM_JOOMGALLERY_GPSTAGS')) + ); + + // IPTC + require_once JPATH_COMPONENT.'/includes/iptcarray.php'; + + $iptctags = explode(',', $this->_config->get('jg_iptctags')); + + $iptc_definitions = array( + 1 => array ('TAG' => 'IPTC', 'JG' => $iptctags, 'NAME' => 'jg_iptctags[]', 'HEAD' => JText::_('COM_JOOMGALLERY_IPTCTAGS')), + ); + + // Include javascript for form validation, cleaning and submitting + $this->_doc->addScript($this->_ambit->getScript('config.js')); + + JText::script('COM_JOOMGALLERY_CONFIG_GS_PD_ALERT_THUMBNAIL_PATH_SUPPORT'); + + $this->assignRef('display', $display); + $this->assignRef('cssfilemsg', $cssfilemsg); + $this->assignRef('exifmsg', $exifmsg); + $this->assignRef('gdmsg', $gdmsg); + $this->assignRef('immsg', $immsg); + $this->assignRef('write_pathimages', $write_pathimages); + $this->assignRef('write_pathoriginalimages', $write_pathoriginalimages); + $this->assignRef('write_paththumbs', $write_paththumbs); + $this->assignRef('write_pathftpupload', $write_pathftpupload); + $this->assignRef('write_pathtemp', $write_pathtemp); + $this->assignRef('write_pathwm', $write_pathwm); + $this->assignRef('wmfilemsg', $wmfilemsg); + $this->assignRef('exif_definitions', $exif_definitions); + $this->assignRef('exif_config_array', $exif_config_array); + $this->assignRef('iptc_definitions', $iptc_definitions); + $this->assignRef('iptc_config_array', $iptc_config_array); + + $this->addToolbar(); + + if(!$this->_mainframe->input->getBool('hidemainmenu')) + { + $this->sidebar = JHtmlSidebar::render(); + } + + parent::display(); + } + + function addToolbar() + { + $title = JText::_('COM_JOOMGALLERY_CONFIG_CONFIGURATION_MANAGER'); + if($this->_config->isExtended()) + { + $config_title = $this->get('ConfigTitle'); + if(JRequest::getInt('id') == 1) + { + $config_title = JText::sprintf('COM_JOOMGALLERY_CONFIGS_DEFAULT_TITLE', $config_title); + } + + $title .= ' :: '.JText::sprintf('COM_JOOMGALLERY_CONFIG_EDIT_TITLE', $config_title); + } + + JToolBarHelper::title($title, 'equalizer'); + JToolbarHelper::apply('apply'); + JToolbarHelper::save('save'); + if($this->_config->isExtended()) + { + JToolBarHelper::cancel('cancel', 'JTOOLBAR_CANCEL'); + } + } + + function getPath($type) + { + switch($type) + { + case 'thumb': + $path = JPath::clean(JPATH_ROOT.'/'.$this->_config->get('jg_paththumbs')); + if(!JFolder::exists($path)) + { + $path = JPath::clean($this->_config->get('jg_paththumbs')); + } + break; + case 'img': + $path = JPath::clean(JPATH_ROOT.'/'.$this->_config->get('jg_pathimages')); + if(!JFolder::exists($path)) + { + $path = JPath::clean($this->_config->get('jg_pathimages')); + } + break; + case 'orig': + $path = JPath::clean(JPATH_ROOT.'/'.$this->_config->get('jg_pathoriginalimages')); + if(!JFolder::exists($path)) + { + $path = JPath::clean($this->_config->get('jg_pathoriginalimages')); + } + break; + case 'ftp': + $path = JPath::clean(JPATH_ROOT.'/'.$this->_config->get('jg_pathftpupload')); + if(!JFolder::exists($path)) + { + $path = JPath::clean($this->_config->get('jg_pathftpupload')); + } + break; + case 'temp': + $path = JPath::clean(JPATH_ROOT.'/'.$this->_config->get('jg_pathtemp')); + if(!JFolder::exists($path)) + { + $path = JPath::clean($this->_config->get('jg_pathtemp')); + } + break; + default: + $path = JPath::clean(JPATH_ROOT.'/'.$this->_config->get('jg_wmpath')); + if(!JFolder::exists($path)) + { + $path = JPath::clean($this->_config->get('jg_wmpath')); + } + break; + } + + return $path; + } + + /** + * Method to get the field input for a component layout field. + * + * @param string $selected The currently selected layout + * @return string The field input + * @since 3.0 + */ + protected function getComponentLayouts($selected = null) + { + $lang = JFactory::getLanguage(); + + // Get the database object and a new query object + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + + // Build the query + $query->select('e.element, e.name'); + $query->from('#__extensions as e'); + $query->where('e.client_id = 0'); + $query->where('e.type = ' . $db->q('template')); + $query->where('e.enabled = 1'); + + // Set the query and load the templates. + $db->setQuery($query); + $templates = $db->loadObjectList('element'); + + // Build the search paths for component layouts. + $component_path = JPath::clean(JPATH_COMPONENT_SITE.'/views/gallery/tmpl'); + + // Prepare array of component layouts + $component_layouts = array(); + + // Prepare the grouped list + $groups = array(); + + // Add the layout options from the component path. + if(is_dir($component_path) && ($component_layouts = JFolder::files($component_path, '^[^_]*\.xml$', false, true))) + { + // Create the group for the component + $groups['_'] = array(); + $groups['_']['id'] = 'jg_alternative_layout__'; + $groups['_']['text'] = JText::sprintf('JOPTION_FROM_COMPONENT'); + $groups['_']['items'] = array(); + + foreach($component_layouts as $i => $file) + { + // Attempt to load the XML file. + if(!$xml = simplexml_load_file($file)) + { + unset($component_layouts[$i]); + + continue; + } + + // Get the help data from the XML file if present. + if(!$menu = $xml->xpath('layout[1]')) + { + unset($component_layouts[$i]); + + continue; + } + + $menu = $menu[0]; + + // Add an option to the component group + $value = basename($file, '.xml'); + $component_layouts[$i] = $value; + if($lang->hasKey('COM_JOOMGALLERY_LAYOUT_'.strtoupper($value))) + { + $text = JText::_('COM_JOOMGALLERY_LAYOUT_'.strtoupper($value)); + } + else + { + $text = $value; + } + $groups['_']['items'][] = JHtml::_('select.option', '_:' . $value, $text); + } + } + + // Loop on all templates + if($templates) + { + foreach($templates as $template) + { + // Load language file + $lang->load('tpl_' . $template->element . '.sys', JPATH_ROOT, null, false, false) + || $lang->load('tpl_' . $template->element . '.sys',JPATH_ROOT . '/templates/' . $template->element, null, false, false) + || $lang->load('tpl_' . $template->element . '.sys', JPATH_ROOT, $lang->getDefault(), false, false) + || $lang->load( + 'tpl_' . $template->element . '.sys', JPATH_ROOT . '/templates/' . $template->element, $lang->getDefault(), false, false + ); + + $template_path = JPath::clean(JPATH_ROOT . '/templates/' . $template->element . '/html/' . _JOOM_OPTION . '/gallery'); + + // Add the layout options from the template path. + if(is_dir($template_path) && ($files = JFolder::files($template_path, '^[^_]*\.php$', false, true))) + { + // Files with corresponding XML files are alternate menu items, not alternate layout files + // so we need to exclude these files from the list. + $xml_files = JFolder::files($template_path, '^[^_]*\.xml$', false, true); + for($j = 0, $count = count($xml_files); $j < $count; $j++) + { + $xml_files[$j] = basename($xml_files[$j], '.xml'); + } + foreach($files as $i => $file) + { + // Remove layout files that exist in the component folder or that have XML files + if ((in_array(basename($file, '.php'), $component_layouts)) + || (in_array(basename($file, '.php'), $xml_files))) + { + unset($files[$i]); + } + } + if(count($files)) + { + // Create the group for the template + $groups[$template->name] = array(); + $groups[$template->name]['id'] = $this->id . '_' . $template->element; + $groups[$template->name]['text'] = JText::sprintf('JOPTION_FROM_TEMPLATE', $template->name); + $groups[$template->name]['items'] = array(); + + foreach($files as $file) + { + // Add an option to the template group + $value = basename($file, '.php'); + $text = $lang->hasKey($key = strtoupper('TPL_' . $template->name . '_COM_JOOMGALLERY_GALLERY_LAYOUT_' . strtoupper($value))) ? JText::_($key) : $value; + $groups[$template->name]['items'][] = JHtml::_('select.option', $template->element . ':' . $value, $text); + } + } + } + } + } + + // Prepare HTML code + $html = array(); + + // Add a grouped list + $html[] = JHtml::_( + 'select.groupedlist', $groups, 'jg_alternative_layout', + array('id' => 'jg_alternative_layout', 'group.id' => 'id', 'list.attr' => null, 'list.select' => $selected) + ); + + return implode($html); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/configs/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/configs/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/configs/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/configs/tmpl/default.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/configs/tmpl/default.php new file mode 100644 index 00000000..5eb98d69 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/configs/tmpl/default.php @@ -0,0 +1,186 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$saveOrder = (($listOrder == 'c.ordering' || !$listOrder) && (strtoupper($listDirn) == 'ASC' || !$listDirn) && !$this->state->get('filter.published') && !$this->state->get('filter.search')); +if($saveOrder): + $saveOrderingUrl = 'index.php?option='._JOOM_OPTION.'&controller=config&task=saveorder&format=json'; + JHtml::_('sortablelist.sortable', 'configList', 'adminForm', strtolower($listDirn), $saveOrderingUrl, true, false); +endif; +$sortFields = $this->getSortFields(); ?> + +sidebar)): ?> +
    + sidebar; ?> +
    +
    + +
    + +
    + +
    + + +
    +
    + + pagination->getLimitBox(); ?> +
    +
    + + +
    +
    + + +
    +
    +
    + +
    + + + + + + + + + + + + + + + + + +items as $item): ?> + + + + + + + + + + + +
    + + + + + + + + + + + + + +
    + pagination->getListFooter(); ?> +
    + id); ?> + +title): ?> + + id == 1 ? ''.JText::sprintf('COM_JOOMGALLERY_CONFIGS_DEFAULT_TITLE', $this->escape($item->title)).'' : $this->escape($item->title); ?> + + + + +usergroups && $item->title): ?> +
      +usergroups as $group): ?> +
    • + +
    +title): ?> + Warning + +
    +title): ?> + |—', $item->level); ?> + escape($item->title); ?> + + Warning + + +id != 1): ?> + pagination->orderUpIcon($i, $i > 1, 'orderup', 'JLIB_HTML_MOVE_UP', $saveOrder); ?> + pagination->orderDownIcon($i, $this->pagination->total, $i < count($this->items), 'orderdown', 'JLIB_HTML_MOVE_DOWN', $saveOrder); ?> + + + ordering; ?> + + + id; ?> +
    +
    +

    +
      +
    • +
    • +
    • +
    • +
    +
    +items) == 1): + echo $this->loadTemplate('info'); ?> + + + + + + + + + + + + +
    + +loadTemplate('new'); ?> \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/configs/tmpl/default_info.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/configs/tmpl/default_info.php new file mode 100644 index 00000000..49ceffc5 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/configs/tmpl/default_info.php @@ -0,0 +1,14 @@ + + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/configs/tmpl/default_new.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/configs/tmpl/default_new.php new file mode 100644 index 00000000..3ab0ff74 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/configs/tmpl/default_new.php @@ -0,0 +1,29 @@ + + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/configs/tmpl/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/configs/tmpl/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/configs/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/configs/view.html.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/configs/view.html.php new file mode 100644 index 00000000..1b120f39 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/configs/view.html.php @@ -0,0 +1,82 @@ +items = $this->get('Configs'); + $this->allitems = $this->get('AllConfigs'); + $this->state = $this->get('State'); + $this->pagination = $this->get('Pagination'); + $this->usergroups = $this->get('Usergroups'); + + $this->addToolbar(); + $this->sidebar = JHtmlSidebar::render(); + + parent::display($tpl); + } + + /** + * Add the toolbar and toolbar title. + * + * @return void + * @since 2.0 + */ + protected function addToolbar() + { + require_once JPATH_COMPONENT.'/includes/popup.php'; + + JToolBarHelper::title(JText::_('COM_JOOMGALLERY_CONFIGS_CONFIGURATION_MANAGER'), 'equalizer'); + + $toolbar = JToolbar::getInstance('toolbar'); + $toolbar->appendButton('Popup', 'new', 'JTOOLBAR_NEW', 'index.php?option='._JOOM_OPTION.'&controller=config&layout=new&tmpl=component', 400, 350, 0, 0, '', 'COM_JOOMGALLERY_CONFIGS_NEW_HEADING', 'jg-new-popup', 'new'); + + JToolbarHelper::editList('edit'); + + JToolbarHelper::deleteList('','remove'); + } + + /** + * Returns an array of fields the table can be sorted by + * + * @return array Array containing the field name to sort by as the key and display text as value + * @since 3.0 + */ + protected function getSortFields() + { + return array( + 'c.ordering' => JText::_('JGRID_HEADING_ORDERING'), + 'g.title' => JText::_('COM_JOOMGALLERY_CONFIGS_TITLE'), + 'g.lft' => JText::_('COM_JOOMGALLERY_CONFIGS_GROUP'), + 'c.id' => JText::_('JGRID_HEADING_ID') + ); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/control/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/control/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/control/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/control/tmpl/default.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/control/tmpl/default.php new file mode 100644 index 00000000..6cabd96a --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/control/tmpl/default.php @@ -0,0 +1,133 @@ + +
    +state->get('message') || $this->state->get('extension_message')): ?> + loadTemplate('messages'); ?> + +
    +
    +
    + +
      +items as $item): + $this->item = $item; + echo $this->loadTemplate('button'); + endforeach; ?> +
    +
    +
    +
    +
    + +
    +modules as $module) + { + $output = JModuleHelper::renderModule($module, array('style' => 'well well-small')); + echo $output; + } +?> +
    + + +
    +
    +loadTemplate('popularimages'); ?> +
    +
    +
    +
    +loadTemplate('topdownloads'); ?> +
    +
    +
    +
    +loadTemplate('notapprovedimages'); ?> +
    +
    +
    +
    +loadTemplate('notapprovedcomments'); ?> +
    +
    + +
    +
    + +params->get('show_available_extensions')): ?> +
    +
    + +params->get('show_update_info_text')): ?> +
    + +
    +entry = 1; + $this->datedCount = 0; + if($this->params->get('dated_extensions')): +?> + +datedCount = count($this->dated_extensions); + echo JHtml::_('bootstrap.startPane', 'jg_extension_tab', array('active' => 'jg_tab_dated-extensions')); + echo JHtml::_('bootstrap.addPanel', 'jg_extension_tab', 'jg_tab_dated-extensions'); + foreach($this->dated_extensions as $name => $extension): + $this->extension = $extension; + $this->name = $name; + echo $this->loadTemplate('extension'); + $this->entry++; + if($this->entry <= $this->datedCount): ?> +
    +available_extensions as $name => $extension): + $title = $name; + if(isset($this->installed_extensions[$name])) + { + if(isset($this->dated_extensions[$name])) + { + $title .= ' '.JText::_('COM_JOOMGALLERY_ADMENU_EXTENSION_INSTALLED_BUT_NOT_UPTODATE').''; + } + else + { + $title .= ' '.JText::_('COM_JOOMGALLERY_ADMENU_EXTENSION_INSTALLED').''; + } + } + else + { + $title .= ' '.JText::_('COM_JOOMGALLERY_ADMENU_EXTENSION_NOT_INSTALLED').''; + } + echo JHtml::_('bootstrap.addSlide', 'jg_accord_available-extensions', $title, 'collapse'.$this->entry); + $this->extension = $extension; + $this->name = $name; + echo $this->loadTemplate('availableextension'); + echo JHtml::_('bootstrap.endSlide'); + if($this->entry < (count($this->available_extensions) + $this->datedCount)): + $this->entry++; + endif; + endforeach; + echo JHtml::_('bootstrap.endAccordion'); + if($this->datedCount): + echo JHtml::_('bootstrap.endPanel'); + echo JHtml::_('bootstrap.endPane'); + endif; + ?> +
    +
    + + +
    +
    + +
    +extension['description'])): ?> +
    + extension['description']; ?> +
    +
    +extension['downloadlink']) + && + ((isset($this->installed_extensions[$this->name]) && isset($this->dated_extensions[$this->name])) || !isset($this->installed_extensions[$this->name]))): + if(isset($this->installed_extensions[$this->name]) && isset($this->dated_extensions[$this->name])): + $label = JText::_('COM_JOOMGALLERY_ADMENU_DOWNLOAD_UPDATE_LINK'); + endif; + if(!isset($this->installed_extensions[$this->name])): + $label = JText::_('COM_JOOMGALLERY_ADMENU_DOWNLOAD_INSTALLATION_LINK'); + endif; ?> +
    + +
    + +dated_extensions[$this->name])): ?> + + + +extension['releaselink'])): ?> + + + + + + + +extension['releaselink'])): ?> + + + +
    dated_extensions[$this->name]['installed_version']; ?>
    extension['version']; ?>
    +
    +extension['updatelink']) + && + ((isset($this->installed_extensions[$this->name]) && isset($this->dated_extensions[$this->name])) || !isset($this->installed_extensions[$this->name]))): + if(isset($this->installed_extensions[$this->name]) && isset($this->dated_extensions[$this->name])): + $label = JText::_('COM_JOOMGALLERY_ADMENU_AUTOUPDATE_LINK'); + endif; + if(!isset($this->installed_extensions[$this->name])): + $label = JText::_('COM_JOOMGALLERY_ADMENU_AUTOINSTALLATION_LINK'); + endif; + if($this->params->get('curl_loaded')): ?> +
    + +params->get('curl_loaded')): + if($this->params->get('url_fopen_allowed')): ?> +
    +
    + + + + + +
    +
    +
    +
    +params->get('url_fopen_allowed')): + if(isset($this->installed_extensions[$this->name])): + $label = JText::_('COM_JOOMGALLERY_ADMENU_AUTOUPDATE_NOT_POSSIBLE'); + endif; + if(!isset($this->installed_extensions[$this->name])): + $label = JText::_('COM_JOOMGALLERY_ADMENU_AUTOINSTALLATION_NOT_POSSIBLE'); + endif; ?> +
    + +
    \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/control/tmpl/default_button.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/control/tmpl/default_button.php new file mode 100644 index 00000000..61dd8256 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/control/tmpl/default_button.php @@ -0,0 +1,7 @@ + +
  • + + item->img, JText::_($this->item->title)); ?> + item->title); ?> + +
  • \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/control/tmpl/default_extension.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/control/tmpl/default_extension.php new file mode 100644 index 00000000..40875668 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/control/tmpl/default_extension.php @@ -0,0 +1,53 @@ + +
    +
    + '.JText::sprintf('COM_JOOMGALLERY_ADMENU_EXTENSION_NOT_UPTODATE', $this->name).''; ?> +
    +
    + + + + +extension['releaselink'])): ?> + + + + + + +extension['releaselink'])): ?> + + + +
    extension['installed_version']; ?>
    extension['version']; ?>
    +
    +extension['downloadlink'])): ?> +
    +extension['updatelink'])): + if($this->params->get('curl_loaded')): ?> +
    + +params->get('curl_loaded')): + if($this->params->get('url_fopen_allowed')): ?> +
    +
    + + + + + +
    +
    +
    + +
    +params->get('url_fopen_allowed')): ?> +
    + +
    \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/control/tmpl/default_messages.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/control/tmpl/default_messages.php new file mode 100644 index 00000000..269493dd --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/control/tmpl/default_messages.php @@ -0,0 +1,14 @@ +state->get('message')): ?> +
    +
    + state->get('message'); ?> +
    +
    +state->get('extension_message')): ?> +
    +
    + state->get('extension_message'); ?> +
    +
    + array('reject', 'COM_JOOMGALLERY_COMMON_APPROVED', 'COM_JOOMGALLERY_COMMAN_REJECT_COMMENT', 'COM_JOOMGALLERY_COMMON_APPROVED', false, 'publish', 'publish'), + 0 => array('approve', 'COM_JOOMGALLERY_COMMON_REJECTED', 'COM_JOOMGALLERY_COMMAN_APPROVE_COMMENT', 'COM_JOOMGALLERY_COMMON_REJECTED', false, 'unpublish', 'unpublish')); +?> +
    + +notApprovedComments)): ?> + + +notApprovedComments as $i => $item): ?> + + + + + + + + + +
    + approved, $i, '', false); ?> + + + + + cmttext; ?> + + escape($item->cmtname); ?> + + cmtdate, JText::_('DATE_FORMAT_LC4')); ?> +
    + +
    + +
    + +
    \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/control/tmpl/default_notapprovedimages.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/control/tmpl/default_notapprovedimages.php new file mode 100644 index 00000000..30bd8a56 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/control/tmpl/default_notapprovedimages.php @@ -0,0 +1,39 @@ + array('reject', 'COM_JOOMGALLERY_COMMON_APPROVED', 'COM_JOOMGALLERY_IMGMAN_REJECT_IMAGE', 'COM_JOOMGALLERY_COMMON_APPROVED', false, 'publish', 'publish'), + 0 => array('approve', 'COM_JOOMGALLERY_COMMON_REJECTED', 'COM_JOOMGALLERY_IMGMAN_APPROVE_IMAGE', 'COM_JOOMGALLERY_COMMON_REJECTED', false, 'unpublish', 'unpublish')); +?> +
    + +notApprovedImages)): ?> + + +notApprovedImages as $i => $item): ?> + + + + + + + + +
    + approved, $i, '', false); ?> + + + + + escape($item->imgtitle); ?> + + escape($item->category_name)); ?> + + + imgdate, JText::_('DATE_FORMAT_LC4')); ?> +
    + +
    + +
    + +
    \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/control/tmpl/default_popularimages.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/control/tmpl/default_popularimages.php new file mode 100644 index 00000000..015f3133 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/control/tmpl/default_popularimages.php @@ -0,0 +1,39 @@ + +
    + +popularImages)): ?> + + +popularImages as $i => $item): + $canEdit = $this->_user->authorise('core.edit', _JOOM_OPTION.'.image.'.$item->id); + $canEditOwn = $this->_user->authorise('core.edit.own', _JOOM_OPTION.'.image.'.$item->id) && $item->owner == $this->_user->get('id'); +?> + + + + + + + + +
    + hits;?> + + id) : null, true); ?> + + + + escape($item->imgtitle); ?> + + escape($item->imgtitle); ?> + + + escape($item->category_name)); ?> + + + imgdate, JText::_('DATE_FORMAT_LC4')); ?> +
    + +
    \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/control/tmpl/default_topdownloads.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/control/tmpl/default_topdownloads.php new file mode 100644 index 00000000..074edaaf --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/control/tmpl/default_topdownloads.php @@ -0,0 +1,39 @@ + +
    + +topDownloads)): ?> + + +topDownloads as $i => $item): + $canEdit = $this->_user->authorise('core.edit', _JOOM_OPTION.'.image.'.$item->id); + $canEditOwn = $this->_user->authorise('core.edit.own', _JOOM_OPTION.'.image.'.$item->id) && $item->owner == $this->_user->get('id'); +?> + + + + + + + + +
    + downloads;?> + + id) : null, true); ?> + + + + escape($item->imgtitle); ?> + + escape($item->imgtitle); ?> + + + escape($item->category_name)); ?> + + + imgdate, JText::_('DATE_FORMAT_LC4')); ?> +
    + +
    \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/control/tmpl/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/control/tmpl/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/control/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/control/view.html.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/control/view.html.php new file mode 100644 index 00000000..a1d2824f --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/control/view.html.php @@ -0,0 +1,92 @@ +params = JComponentHelper::getParams('com_joomgallery'); + + JToolBarHelper::title(JText::_('COM_JOOMGALLERY_ADMENU_ADMINMENU') , 'joomgallery'); + + $this->canDo = JoomHelper::getActions(); + if($this->canDo->get('core.admin')) + { + JToolBarHelper::preferences('com_joomgallery'); + JToolBarHelper::spacer(); + } + + // Get data from the model + $model = $this->getModel(); + $this->state = $model->getState(); + $this->items = $model->getData(); + $this->popularImages = $model->getImages('a.hits desc', true, 5, 'a.hits > 0'); + $this->notApprovedImages = $model->getImages('a.imgdate desc', false, 5); + $this->notApprovedComments = $model->getComments('c.cmtdate desc', false, 5); + $this->topDownloads = $model->getImages('a.downloads desc', true, 5, 'a.downloads > 0'); + + $lang = JFactory::getLanguage(); + + $this->modules =& JModuleHelper::getModules('joom_cpanel'); + + if($this->_config->get('jg_checkupdate')) + { + $available_extensions = JoomExtensions::getAvailableExtensions(); + $this->params->set('url_fopen_allowed', @ini_get('allow_url_fopen')); + $this->params->set('curl_loaded', extension_loaded('curl')); + + // If there weren't any available extensions found + // loading the RSS feed wasn't successful + if(count($available_extensions)) + { + $installed_extensions = JoomExtensions::getInstalledExtensions(); + $this->assignRef('available_extensions', $available_extensions); + $this->assignRef('installed_extensions', $installed_extensions); + $this->params->set('show_available_extensions', 1); + + $dated_extensions = JoomExtensions::checkUpdate(); + if(count($dated_extensions)) + { + $this->assignRef('dated_extensions', $dated_extensions); + $this->params->set('dated_extensions', 1); + } + else + { + $this->params->set('dated_extensions', 0); + $this->params->set('show_update_info_text', 1); + } + } + } + else + { + $this->params->set('dated_extensions', 0); + } + + parent::display($tpl); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/cssedit/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/cssedit/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/cssedit/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/cssedit/tmpl/default.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/cssedit/tmpl/default.php new file mode 100644 index 00000000..ccc8e592 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/cssedit/tmpl/default.php @@ -0,0 +1,26 @@ + +
    +sidebar)): ?> +
    + sidebar; ?> +
    +
    + +
    + +
    +
    + edit)? JText::_('COM_JOOMGALLERY_CSSMAN_EDIT_CSS_EXPLANATION') : JText::_('COM_JOOMGALLERY_CSSMAN_NEW_CSS_EXPLANATION'); ?> +
    +
    +
    + file ?>
    + +
    + + + + + +
    + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/cssedit/tmpl/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/cssedit/tmpl/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/cssedit/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/cssedit/view.html.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/cssedit/view.html.php new file mode 100644 index 00000000..1c0927bd --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/cssedit/view.html.php @@ -0,0 +1,95 @@ +assignRef('content', $content); + $this->assignRef('edit', $edit); + $this->assignRef('file', $file); + + $this->sidebar = JHtmlSidebar::render(); + + parent::display($tpl); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/editimages/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/editimages/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/editimages/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/editimages/tmpl/form.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/editimages/tmpl/form.php new file mode 100644 index 00000000..e10c0308 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/editimages/tmpl/form.php @@ -0,0 +1,141 @@ + + +
    +
    +
    +
    +
    + form->getLabel('imgtitle'); ?> +
    +
    + form->getInput('imgtitle'); ?> + form->getInput('imgtitlestartcounter'); ?> +
    +
    +
    +
    + form->getLabel('catid'); ?> +
    +
    +
    form->getInput('catid'); ?>
    + form->getInput('movecopy'); ?> +
    +
    +
    +
    + form->getLabel('access'); ?> +
    +
    + form->getInput('access'); ?> +
    +
    +
    +
    + form->getLabel('imgtext'); ?> +
    +
    + form->getInput('imgtext'); ?> +
    +
    +
    +
    + form->getLabel('owner'); ?> +
    +
    + form->getInput('owner'); ?> +
    +
    +
    +
    + form->getLabel('imgauthor'); ?> +
    +
    + form->getInput('imgauthor'); ?> +
    +
    +
    +
    + form->getLabel('metadesc'); ?> +
    +
    + form->getInput('metadesc'); ?> +
    +
    +
    +
    + form->getLabel('metakey'); ?> +
    +
    + form->getInput('metakey'); ?> +
    +
    +
    +
    + form->getLabel('published'); ?> +
    +
    + form->getInput('published'); ?> +
    +
    +
    +
    + form->getLabel('txtclearvotes'); ?> +
    +
    + form->getInput('txtclearvotes'); ?> + form->getInput('clearvotes'); ?> +
    +
    +
    +
    + form->getLabel('txtclearhits'); ?> +
    +
    + form->getInput('txtclearhits'); ?> + form->getInput('clearhits'); ?> +
    +
    +
    +
    + form->getLabel('txtcleardownloads'); ?> +
    +
    + form->getInput('txtcleardownloads'); ?> + form->getInput('cleardownloads'); ?> +
    +
    +
    +
    +
    + + +
    +
    + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/editimages/view.html.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/editimages/view.html.php new file mode 100644 index 00000000..368a4ae5 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/editimages/view.html.php @@ -0,0 +1,78 @@ +get('Images'); + + $cids = JRequest::getVar('cid', array(), '', 'array'); + $cids = implode(',', $cids); + + // Get the form and fill the fields + $form = $this->get('Form'); + + // Set maximum allowed user count to switch from listbox to modal popup selection + $form->setFieldAttribute('owner', 'useListboxMaxUserCount', $this->_config->get('jg_use_listbox_max_user_count')); + + // Bind the data to the form + $form->bind($items[0]); + + // Set some form fields manually + $form->setValue('txtclearhits', null, JText::_('COM_JOOMGALLERY_IMGMAN_CLEAR_HITS_FOR_ALL_IMAGES')); + $form->setValue('txtclearvotes', null, JText::_('COM_JOOMGALLERY_IMGMAN_CLEAR_VOTES_FOR_ALL_IMAGES')); + $form->setValue('txtcleardownloads', null, JText::_('COM_JOOMGALLERY_IMGMAN_CLEAR_DOWNLOADS_FOR_ALL_IMAGES')); + + $this->assignRef('items', $items); + $this->assignRef('cids', $cids); + $this->assignRef('form', $form); + + $this->addToolbar(); + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @access public + * @return void + * + * @since 2.0 + */ + function addToolbar() + { + JToolBarHelper::title(JText::_('COM_JOOMGALLERY_IMGMAN_IMAGE_MANAGER').' :: '.JText::_('COM_JOOMGALLERY_FIELDSET_EDITIMAGES'), 'images'); + + JToolbarHelper::apply('apply'); + JToolbarHelper::save('save'); + JToolbarHelper::cancel('cancel'); + JToolbarHelper::spacer(); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/ftpupload/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/ftpupload/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/ftpupload/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/ftpupload/tmpl/default.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/ftpupload/tmpl/default.php new file mode 100644 index 00000000..1519db12 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/ftpupload/tmpl/default.php @@ -0,0 +1,129 @@ + +
    +sidebar)): ?> +
    + sidebar; ?> +
    +
    + +
    + +
    +
    +

    + +
    + form->getLabel('directory'); ?> +
    + form->getInput('directory'); ?> +
    +
    +
    +
    +
    +
    +
    + form->getInput('subdirectory')): ?> +
    + form->getLabel('subdirectory'); ?> +
    + +
    +
    + +
    + form->getLabel('ftpfiles'); ?> +
    + form->getInput('ftpfiles'); ?> +
    +
    +
    +
    +
    +
    + form->getLabel('catid'); ?> +
    + form->getInput('catid'); ?> +
    +
    + _config->get('jg_useorigfilename')): ?> +
    + form->getLabel('imgtitle'); ?> +
    + form->getInput('imgtitle'); ?> +
    +
    + _config->get('jg_useorigfilename') && $this->_config->get('jg_filenamenumber')): ?> +
    + form->getLabel('filecounter'); ?> +
    + form->getInput('filecounter'); ?> +
    +
    + +
    + form->getLabel('imgtext'); ?> +
    + form->getInput('imgtext'); ?> +
    +
    +
    + form->getLabel('imgauthor'); ?> +
    + form->getInput('imgauthor'); ?> +
    +
    +
    + form->getLabel('published'); ?> +
    + form->getInput('published'); ?> +
    +
    +
    + form->getLabel('access'); ?> +
    + form->getInput('access'); ?> +
    +
    +
    + form->getLabel('file_delete'); ?> +
    + form->getInput('file_delete'); ?> +
    +
    + _config->get('jg_delete_original') == 2): ?> +
    + form->getLabel('original_delete'); ?> +
    + form->getInput('original_delete'); ?> +
    +
    + +
    + form->getLabel('create_special_gif'); ?> +
    + form->getInput('create_special_gif'); ?> +
    +
    +
    + form->getLabel('debug'); ?> +
    + form->getInput('debug'); ?> +
    +
    +
    +
    + +
    +
    +
    +
    + + + + +
    + diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/ftpupload/tmpl/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/ftpupload/tmpl/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/ftpupload/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/ftpupload/view.html.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/ftpupload/view.html.php new file mode 100644 index 00000000..49e8c267 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/ftpupload/view.html.php @@ -0,0 +1,55 @@ +form = JForm::getInstance(_JOOM_OPTION.'.ftpupload', 'ftpupload'); + + $subdirectory = $this->_mainframe->getUserStateFromRequest('joom.upload.ftp.subdirectory', 'subdirectory', '/', '', 'string'); + + $this->form->setFieldAttribute('directory', 'default', JPath::clean($this->_ambit->get('ftp_path').$subdirectory)); + $this->form->setFieldAttribute('subdirectory', 'directory', $this->_ambit->get('ftp_path')); + $this->form->setFieldAttribute('ftpfiles', 'directory', $this->_ambit->get('ftp_path').$subdirectory); + $this->form->setFieldAttribute('subdirectory', 'default', $subdirectory); + $this->form->setFieldAttribute('access', 'default', (int) JFactory::getConfig()->get('access')); + + if($this->_config->get('jg_useorigfilename')) + { + $this->form->setFieldAttribute('imgtitle', 'required', 'false'); + } + + $this->sidebar = JHtmlSidebar::render(); + + parent::display($tpl); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/help/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/help/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/help/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/help/tmpl/default.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/help/tmpl/default.php new file mode 100644 index 00000000..91618405 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/help/tmpl/default.php @@ -0,0 +1,142 @@ + +sidebar)): ?> +
    + sidebar; ?> +
    +
    + +
    + +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + +
    + + german  + + http://www.joomgallery.net +
    + + english  + + http://www.en.joomgallery.net/ +
    + + german  + + http://www.forum.joomgallery.net/ +
    + + english  + + http://www.forum.en.joomgallery.net/ +
    + + english  + + +
    +
    +
    +
    +
    + +
    +

    JoomGallery::ProjectTeam', 'GitHub'); ?>

    +

    +

    + GitHub Logo
    +
    +
    +
    +
    +
    +
    + +
    ¹
    + +
    ¹
    +
    +
    + +
    +
    + +
      +credits as $credit): ?> +
    • + +
      Author: + +
    • + +
    +
    +
    +
    +
    +
    +
    + +
    +

    +

    + + Donate! +

    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +loadTemplate('changelog'); \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/help/tmpl/default_changelog.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/help/tmpl/default_changelog.php new file mode 100644 index 00000000..7fbf2bb4 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/help/tmpl/default_changelog.php @@ -0,0 +1,19 @@ + + + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/help/tmpl/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/help/tmpl/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/help/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/help/view.html.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/help/view.html.php new file mode 100644 index 00000000..84d5271e --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/help/view.html.php @@ -0,0 +1,201 @@ + array( 'translator' => 'JoomGallery::ProjectTeam de-DE (formal)', + 'downloadlink' => 'http://www.joomgallery.net/downloads/joomgallery-fuer-joomla-3/sprachdateien/die-deutschen-formellen-sprachdateien.html', + 'flag' => 'de.png', + 'type' => 'formal'), + 'de-DE-informal' => array( 'translator' => 'JoomGallery::ProjectTeam de-DE (informal)', + 'downloadlink' => 'http://www.joomgallery.net/downloads/joomgallery-fuer-joomla-3/sprachdateien/die-deutschen-informellen-sprachdateien.html', + 'flag' => 'de.png'), + 'ar-AA' => array( 'translator' => 'JoomGallery::TranslationTeam::Arabic ar-AA', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-arabic-unitag-language-files.html', + 'flag' => 'sy.png'), + 'bs-BA' => array( 'translator' => 'JoomGallery::TranslationTeam::Bosnian (Bosnia and Herzegovina) bs-BA', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-bosnian-language-files.html', + 'flag' => 'ba.png'), + 'bg-BG' => array( 'translator' => 'JoomGallery::TranslationTeam::Bulgarian (Bulgaria) bg-BG', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-bulgarian-language-files.html', + 'flag' => 'bg.png'), + 'zh-CN' => array( 'translator' => 'JoomGallery::TranslationTeam::Chinese (China) zh-CN', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-chinese-simplified-language-files.html', + 'flag' => 'cn.png'), + 'zh-TW' => array( 'translator' => 'JoomGallery::TranslationTeam::Chinese (Taiwan) zh-TW', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-chinese-traditional-language-files.html', + 'flag' => 'cn.png'), + 'hr-HR' => array( 'translator' => 'JoomGallery::TranslationTeam::Croatian (Croatia) hr-HR', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-croatian-language-files.html', + 'flag' => 'hr.png'), + 'cs-CZ' => array( 'translator' => 'JoomGallery::TranslationTeam::Czech (Czech Republic) cs-CZ', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-czech-language-files.html', + 'flag' => 'cz.png'), + 'da-DK' => array( 'translator' => 'JoomGallery::TranslationTeam::Danish (Denmark) da-DK', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-danish-language-files.html', + 'flag' => 'dk.png'), + 'nl-NL' => array( 'translator' => 'JoomGallery::TranslationTeam::Dutch (Netherlands) nl-NL', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-dutch-language-files.html', + 'flag' => 'nl.png'), + 'fi-FI' => array( 'translator' => 'JoomGallery::TranslationTeam::Finnish (Finland) fi-FI', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-finnish-language-files.html', + 'flag' => 'fi.png'), + 'fr-FR' => array( 'translator' => 'JoomGallery::TranslationTeam::French (France) fr-FR', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-french-language-files.html', + 'flag' => 'fr.png'), + 'el-GR' => array( 'translator' => 'JoomGallery::TranslationTeam::Greek (Greece) el-GR', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-greek-language-files.html', + 'flag' => 'gr.png'), + 'hu-HU-formal' => array( 'translator' => 'JoomGallery::TranslationTeam::Hungarian (Hungary) hu-HU (formal)', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-hungarian-formal-language-files.html', + 'flag' => 'hu.png'), + 'hu-HU-informal' => array( 'translator' => 'JoomGallery::TranslationTeam::Hungarian (Hungary) hu-HU (informal)', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-hungarian-informal-language-files.html', + 'flag' => 'hu.png'), + 'it-IT' => array( 'translator' => 'JoomGallery::TranslationTeam::Italian (Italy) it-IT', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-italian-language-files.html', + 'flag' => 'it.png'), + 'ja-JP' => array( 'translator' => 'JoomGallery::TranslationTeam::Japanese (Japan) ja-JP', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-japanese-language-files.html', + 'flag' => 'jp.png'), + 'lt-LT' => array( 'translator' => 'JoomGallery::TranslationTeam::Lithuanian (Lithuania) lt-LT', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-lithunian-language-files.html', + 'flag' => 'lt.png'), + 'lv-LV' => array( 'translator' => 'JoomGallery::TranslationTeam::Latvian (Latvia) lv-LV', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-latvian-language-files.html', + 'flag' => 'lv.png'), + 'nb-NO' => array( 'translator' => 'JoomGallery::TranslationTeam::Norwegian Bokmål (Norway) nb-NO', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-norwegian-language-files.html', + 'flag' => 'no.png'), + 'fa-IR' => array( 'translator' => 'JoomGallery::TranslationTeam::Persian (Iran) fa-IR', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-persian-language-files.html', + 'flag' => 'ir.png'), + 'pl-PL' => array( 'translator' => 'JoomGallery::TranslationTeam::Polish (Poland) pl-PL', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-polish-language-files.html', + 'flag' => 'pl.png'), + 'pt-BR' => array( 'translator' => 'JoomGallery::TranslationTeam::Portuguese (Brazil) pt-BR', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-portuguese-brazilian-language-files.html', + 'flag' => 'br.png'), + 'pt-PT' => array( 'translator' => 'JoomGallery::TranslationTeam::Portuguese (Portugal) pt-PT', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-portuguese-language-files.html', + 'flag' => 'pt.png'), + 'ru-RU' => array( 'translator' => 'JoomGallery::TranslationTeam::Russian (Russia) ru-RU', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-russian-language-files.html', + 'flag' => 'ru.png'), + 'sr-RS' => array( 'translator' => 'JoomGallery::TranslationTeam::Serbian (Serbia) sr-RS', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-serbian-cyrillic-language-files.html', + 'flag' => 'rs.png'), + 'sr-YU' => array( 'translator' => 'JoomGallery::TranslationTeam::Serbian sr-YU', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-serbian-language-files.html', + 'flag' => 'rs.png'), + 'sk-SK' => array( 'translator' => 'JoomGallery::TranslationTeam::Slovak (Slovakia) sk-SK', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-slovak-language-files.html', + 'flag' => 'sk.png'), + 'sl-SI' => array( 'translator' => 'JoomGallery::TranslationTeam::Slovenian (Slovenia) sl-SI', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-slovenian-language-files.html', + 'flag' => 'si.png'), + 'es-ES' => array( 'translator' => 'JoomGallery::TranslationTeam::Spanish (Spain) es-ES', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-spanish-language-files.html', + 'flag' => 'es.png'), + 'sv-SE' => array( 'translator' => 'JoomGallery::TranslationTeam::Swedish (Sweden) sv-SE', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-swedish-language-files.html', + 'flag' => 'se.png'), + 'tr-TR' => array( 'translator' => 'JoomGallery::TranslationTeam::Turkish (Turkey) tr-TR', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-turkish-language-files.html', + 'flag' => 'tr.png'), + 'uk-UA' => array( 'translator' => 'JoomGallery::TranslationTeam::Ukrainian (Ukraine) uk-UA', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-ukrainian-language-files.html', + 'flag' => 'ua.png'), + 'vi-VN' => array( 'translator' => 'JoomGallery::TranslationTeam::Vietnamese (Viet Nam) vi-VN', + 'downloadlink' => 'http://www.en.joomgallery.net/downloads/joomgallery-for-joomla-3/languages/the-vietnamese-language-files.html', + 'flag' => 'vn.png') + ); + + $credits = array(array('title' => 'Joomla!', + 'author' => '', + 'link' => 'http://www.joomla.org'), + array('title' => 'jQuery Thumbnail Scroller - Detail view', + 'author' => 'Manos Malihutsakis', + 'link' => 'http://manos.malihu.gr/jquery-thumbnail-scroller'), + array('title' => 'Slimbox (modified) - Detail and Category view', + 'author' => 'Christophe Beyls', + 'link' => 'http://www.digitalia.be/software/slimbox'), + array('title' => 'Thickbox3.1 (modified) - Detail and Category view', + 'author' => 'Cody Lindley', + 'link' => 'http://www.codylindley.com'), + array('title' => 'pngbehavior.htc (PNG in IE6)', + 'author' => 'Erik Arvidsson', + 'link' => 'http://webfx.eae.net'), + array('title' => 'ImageMagick', + 'author' => 'ImageMagick Studio LLC', + 'link' => 'http://www.imagemagick.org/script/index.php'), + array('title' => 'Jupload - Java Applet for uploading', + 'author' => 'Etienne Gauthier', + 'link' => 'http://jupload.sourceforge.net/'), + array('title' => 'Watermark (modified)', + 'author' => 'Michael Mueller', + 'link' => 'http://www.php4u.net'), + array('title' => 'fastimagecopyresampled (fast conversion of pictures in GD)', + 'author' => 'Tim Eckel', + 'link' => 'http://de.php.net/manual/en/function.imagecopyresampled.php#77679'), + array('title' => 'Wonderful Icons', + 'author' => 'Mark James', + 'link' => 'http://www.famfamfam.com'), + array('title' => 'Smoothgallery (modified) slideshow in detail view', + 'author' => 'Jonathan Schemoul', + 'link' => 'http://smoothgallery.jondesign.net'), + array('title' => 'Resize Image with Different Aspect Ratio - resizing thumbnails', + 'author' => 'Nash', + 'link' => 'http://nashruddin.com/Resize_Image_to_Different_Aspect_Ratio_on_the_fly'), + array('title' => 'Weighted rating according to Thomas Bayes', + 'author' => 'Michael Jašek', + 'link' => 'http://www.buntesuppe.de/blog/123/bayessche-bewertung'), + array('title' => 'Fine Uploader', + 'author' => 'Ray Nicholus, Andrew Valums', + 'link' => 'http://fineuploader.com') + ); + + $params = JComponentHelper::getParams('com_joomgallery'); + if($this->_config->get('jg_checkupdate') && extension_loaded('curl')) + { + $params->set('autoinstall_possible', 1); + } + + $this->languages = $languages; + $this->credits = $credits; + $this->params = $params; + + $this->sidebar = JHtmlSidebar::render(); + + parent::display($tpl); + } +} diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/image/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/image/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/image/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/image/tmpl/form.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/image/tmpl/form.php new file mode 100644 index 00000000..f64a59dd --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/image/tmpl/form.php @@ -0,0 +1,362 @@ + + +
    +
    + +
    + + + +
    + + +
    +
    +
    +
    +
    + form->getLabel('imgtitle'); ?> +
    +
    + form->getInput('imgtitle'); ?> +
    +
    +
    +
    + form->getLabel('alias'); ?> +
    +
    + form->getInput('alias'); ?> +
    +
    +
    +
    + form->getLabel('catid'); ?> +
    +
    + form->getInput('catid'); ?> +
    +
    +
    +
    + form->getLabel('published'); ?> +
    +
    + form->getInput('published'); ?> +
    +
    +
    +
    + form->getLabel('hidden'); ?> +
    +
    + form->getInput('hidden'); ?> +
    +
    +
    +
    + form->getLabel('featured'); ?> +
    +
    + form->getInput('featured'); ?> +
    +
    +
    +
    + form->getLabel('access'); ?> +
    +
    + form->getInput('access'); ?> +
    +
    +
    +isNew): ?> +
    +
    +
    + form->getLabel('id'); ?> +
    +
    + form->getInput('id'); ?> +
    +
    +
    +
    + form->getLabel('publishhiddenstate'); ?> +
    +
    + form->getInput('publishhiddenstate'); ?> +
    +
    +
    +
    + form->getLabel('hits'); ?> +
    +
    + form->getInput('hits'); ?> +item->hits): ?> + + +
    +
    +
    +
    + form->getLabel('downloads'); ?> +
    +
    + form->getInput('downloads'); ?> +item->downloads): ?> + + +
    +
    +
    +
    + form->getLabel('rating'); ?> +
    +
    + form->getInput('rating'); ?> +item->imgvotes): ?> + + +
    +
    +
    +
    + form->getLabel('date'); ?> +
    +
    + form->getInput('date'); ?> +
    +
    +
    + +
    +
    +
    + form->getLabel('detail_catid'); ?> +
    +
    + form->getInput('detail_catid'); ?> +
    +
    +
    +
    + form->getLabel('imgfilename'); ?> +
    +
    + form->getInput('imgfilename'); ?> +
    +
    +
    +
    + form->getLabel('original_exists'); ?> +
    +
    + form->getInput('original_exists'); ?> +
    +
    +
    +
    + form->getLabel('copy_original'); ?> +
    +
    + form->getInput('copy_original'); ?> +
    +
    +
    +
    + form->getLabel('thumb_catid'); ?> +
    +
    + form->getInput('thumb_catid'); ?> +
    +
    +
    +
    + form->getLabel('imgthumbname'); ?> +
    +
    + form->getInput('imgthumbname'); ?> +
    +
    +
    + +
    +
    +
    +
    +
    + form->getLabel('imgtext'); ?> +
    +
    + form->getInput('imgtext'); ?> +
    +
    +
    +
    + form->getLabel('imagelib'); ?> +
    +
    + form->getInput('imagelib'); ?> +
    +
    +
    +
    + form->getLabel('imagelib2'); ?> +
    +
    + form->getInput('imagelib2'); ?> +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + form->getLabel('owner'); ?> +
    +
    + form->getInput('owner'); ?> +
    +
    +
    +
    + form->getLabel('imgauthor'); ?> +
    +
    + form->getInput('imgauthor'); ?> +
    +
    +
    +
    + loadTemplate('options'); ?> +
    +
    +
    + + +isNew): ?> +
    +
    +
    + form->getLabel('spacer', 'files'); ?> +
    +
    + form->getInput('spacer', 'files'); ?> +
    +
    +
    +
    + form->getLabel('thumb', 'files'); ?> +
    +
    + form->getInput('thumb', 'files'); ?> +
    +
    +
    +
    + form->getLabel('img', 'files'); ?> +
    +
    + form->getInput('img', 'files'); ?> +
    +
    +
    +
    + form->getLabel('orig', 'files'); ?> +
    +
    + form->getInput('orig', 'files'); ?> +
    +
    +
    + + + +
    + loadTemplate('metadata'); ?> +
    + + +_user->authorise('core.admin', _JOOM_OPTION.'.image.'.$this->item->id)): ?> +
    + form->getInput('rules'); ?> +
    + + + +
    +
    + + + + +
    +
    + +
    +
    + form->getLabel('metadesc'); ?> +
    +
    + form->getInput('metadesc'); ?> +
    +
    +
    +
    + form->getLabel('metakey'); ?> +
    +
    + form->getInput('metakey'); ?> +
    +
    +form->getGroup('metadata') as $field): ?> +
    + hidden): ?> +
    + input; ?> +
    + +
    + label; ?> +
    +
    + input; ?> +
    + +
    + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/image/tmpl/form_options.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/image/tmpl/form_options.php new file mode 100644 index 00000000..b63e731c --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/image/tmpl/form_options.php @@ -0,0 +1,24 @@ + 'collapse0')); +$fieldSets = $this->form->getFieldsets(); +$i = 0; +foreach($fieldSets as $name => $fieldSet): + if($name != ''): + echo JHtml::_('bootstrap.addSlide', 'imageOptions', JText::_($fieldSet->label), 'collapse'.$i++); + if(isset($fieldSet->description) && trim($fieldSet->description)): + echo '

    '.$this->escape(JText::_($fieldSet->description)).'

    '; + endif; + foreach($this->form->getFieldset($name) as $field): ?> +
    +
    + label; ?> +
    +
    + input; ?> +
    +
    + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/image/view.html.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/image/view.html.php new file mode 100644 index 00000000..f198e434 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/image/view.html.php @@ -0,0 +1,257 @@ +get('Data'); + $isNew = ($item->id < 1); + $rating = 0.0; + + // Get the form and fill the fields + $form = $this->get('Form'); + + if($isNew) + { + // Set some field attributes for javascript validation + $form->setFieldAttribute('detail_catid', 'required', true); + $form->setFieldAttribute('detail_catid', 'validate', 'joompositivenumeric'); + $form->setFieldAttribute('thumb_catid', 'required', true); + $form->setFieldAttribute('thumb_catid', 'validate', 'joompositivenumeric'); + $form->setFieldAttribute('imgfilename', 'required', true); + $form->setFieldAttribute('imgthumbname', 'required', true); + + // Detail images + $detail_catpath = JoomHelper::getCatPath($item->detail_catid); + $detail_path = $this->_ambit->get('img_path').$detail_catpath; + $form->setFieldAttribute('imgfilename', 'directory', $detail_path); + $imgfilename_field = $this->_findFieldByFieldName($form, 'imgfilename'); + $imagelib_field = $this->_findFieldByFieldName($form, 'imagelib2'); + + // Thumbnail images + $thumb_catpath = JoomHelper::getCatPath($item->thumb_catid); + $thumb_path = $this->_ambit->get('thumb_path').$thumb_catpath; + $form->setFieldAttribute('imgthumbname', 'directory', $thumb_path); + $imgthumbname_field = $this->_findFieldByFieldName($form, 'imgthumbname'); + $imagelib_field = $this->_findFieldByFieldName($form, 'imagelib'); + } + else + { + if($item->imgvotes > 0) + { + $rating = JoomHelper::getRating($item->id); + } + } + + // Set maximum allowed user count to switch from listbox to modal popup selection + $form->setFieldAttribute('owner', 'useListboxMaxUserCount', $this->_config->get('jg_use_listbox_max_user_count')); + + // Bind the data to the form + $form->bind($item); + + // Set some form fields manually + if($isNew) + { + // Does the original image file exist + if($form->getValue('imgfilename', null) == '') + { + $form->setValue('original_exists', null, JText::_('COM_JOOMGALLERY_IMGMAN_NO_IMAGE_SELECTED')); + } + else + { + if(JFile::exists($this->_ambit->getImg('orig_path', $item->imgfilename, null, $item->detail_catid))) + { + $orig_msg = JText::_('COM_JOOMGALLERY_IMGMAN_ORIGINAL_EXIST'); + $color = 'green'; + } + else + { + $orig_msg = JText::_('COM_JOOMGALLERY_IMGMAN_ORIGINAL_NOT_EXIST'); + $color = 'red'; + } + $form->setValue('original_exists', null, $orig_msg); + $original_exists_field = $this->_findFieldByFieldName($form, 'original_exists'); + $js = " + window.addEvent('domready', function() { + $('".$original_exists_field->id."').setStyle('color', '".$color."'); + });"; + $this->_doc->addScriptDeclaration($js); + } + } + else + { + // Plublished and hidden state + if($item->published) + { + $form->setValue('publishhiddenstate', null, $item->hidden ? JText::_('COM_JOOMGALLERY_COMMON_PUBLISHED_BUT_HIDDEN') : JText::_('COM_JOOMGALLERY_COMMON_STATE_PUBLISHED') ); + } + else + { + $form->setValue('publishhiddenstate', null, JText::_('COM_JOOMGALLERY_COMMON_STATE_UNPUBLISHED')); + } + // Rating + $form->setValue('rating', null, JText::sprintf('COM_JOOMGALLERY_IMGMAN_IMAGE_VOTES', $rating, $item->imgvotes)); + // Date + $form->setValue('date', null, JHTML::_('date', $item->imgdate, JText::_('DATE_FORMAT_LC2'))); + } + + // Set image source for detail image preview + if($item->imgfilename) + { + if($isNew) + { + // We have to look for the image ID fist because the image may have to be output through the script + $id = $this->getModel()->getIdByFilename($item->imgfilename, $item->detail_catid); + $imgsource = $this->_ambit->getImg('img_url', $id); + } + else + { + $imgsource = $this->_ambit->getImg('img_url', $item); + } + } + else + { + $imgsource = '../media/system/images/blank.png'; + } + $form->setValue('imagelib2', null, $imgsource); + + // Set image source for thumbnail preview + if($item->imgthumbname) + { + if($isNew) + { + // We have to look for the image ID fist because the image may have to be output through the script + $id = $this->getModel()->getIdByFilename($item->imgthumbname, $item->thumb_catid, true); + $thumbsource = $this->_ambit->getImg('thumb_url', $id); + } + else + { + $thumbsource = $this->_ambit->getImg('thumb_url', $item); + } + } + else + { + $thumbsource = '../media/system/images/blank.png'; + } + $form->setValue('imagelib', null, $thumbsource); + + JHtml::_('jquery.framework'); + + $this->assignRef('item', $item); + $this->assignRef('isNew', $isNew); + $this->assignRef('form', $form); + + $this->addToolbar(); + parent::display($tpl); + } + + /** + * Find a form field by field name + * + * @param object $form The form object to search in + * @param string $fieldname The field name to search + * @return mixed The form field object or false, if field could not be found + * @since 2.0 + */ + private function _findFieldByFieldName($form, $fieldname) + { + foreach($form->getFieldset() As $field) + { + if($field->fieldname == $fieldname) + { + return $field; + } + } + + return false; + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 2.0 + */ + public function addToolbar() + { + // Get the results for each action + $canDo = JoomHelper::getActions('image', $this->item->id); + + $title = JText::_('COM_JOOMGALLERY_IMGMAN_IMAGE_MANAGER').' :: '; + + if($this->isNew) + { + $title .= JText::_('COM_JOOMGALLERY_IMGMAN_IMAGE_ADD'); + } + else + { + $title .= JText::_('COM_JOOMGALLERY_IMGMAN_IMAGE_EDIT'); + } + + JToolBarHelper::title($title, 'image'); + + // For new images check the create permission + if($this->isNew && ($this->_config->get('jg_disableunrequiredchecks') || $canDo->get('joom.upload') || count(JoomHelper::getAuthorisedCategories('joom.upload')))) + { + JToolBarHelper::apply('apply', 'JTOOLBAR_APPLY'); + JToolBarHelper::save('save', 'JTOOLBAR_SAVE'); + JToolBarHelper::custom('save2new', 'save-new.png', 'save-new_f2.png', 'JTOOLBAR_SAVE_AND_NEW', false); + } + else + { + if(($canDo->get('core.edit') || ($canDo->get('core.edit.own') && $this->item->owner == $this->_user->get('id')))) + { + JToolBarHelper::apply('apply', 'JTOOLBAR_APPLY'); + JToolBarHelper::save('save', 'JTOOLBAR_SAVE'); + if($canDo->get('joom.upload') || count(JoomHelper::getAuthorisedCategories('joom.upload'))) + { + JToolBarHelper::save2new(); + } + } + } + + // If it's an already existing category a copy may be saved (only if creating categories is allowed) + if(!$this->isNew && ($this->_config->get('jg_disableunrequiredchecks') || $canDo->get('joom.upload') || count(JoomHelper::getAuthorisedCategories('joom.upload')))) + { + // TODO: How to implement save as copy? + //JToolBarHelper::save2copy(); + } + + if($this->isNew) + { + JToolBarHelper::cancel('cancel','JTOOLBAR_CANCEL'); + } + else + { + JToolBarHelper::cancel('cancel', 'JTOOLBAR_CLOSE'); + } + JToolbarHelper::spacer(); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/image/view.raw.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/image/view.raw.php new file mode 100644 index 00000000..727e43f2 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/image/view.raw.php @@ -0,0 +1,70 @@ +get('Data'); + $img = $this->_ambit->getImg($type.'_path', $image); + + if(!JFile::exists($img)) + { + $this->_mainframe->redirect(JRoute::_('index.php', false), JText::_('COM_JOOMGALLERY_COMMON_MSG_IMAGE_NOT_EXIST'), 'error'); + } + + $info = getimagesize($img); + switch($info[2]) + { + case 1: + $mime = 'image/gif'; + break; + case 2: + $mime = 'image/jpeg'; + break; + case 3: + $mime = 'image/png'; + break; + default: + JError::raiseError(404, JText::sprintf('COM_JOOMGALLERY_COMMON_MSG_MIME_NOT_ALLOWED', $info[2])); + break; + } + + // Set mime encoding + $this->_doc->setMimeEncoding($mime); + + // Set header to specify the file name + $disposition = 'inline'; + JResponse::setHeader('Content-disposition', $disposition.'; filename='.basename($img)); + + echo JFile::read($img); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/images/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/images/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/images/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/images/tmpl/default.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/images/tmpl/default.php new file mode 100644 index 00000000..cd1ca5c6 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/images/tmpl/default.php @@ -0,0 +1,204 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$saveOrder = $listOrder == 'a.ordering'; +$columns = 15; +$display_hidden_asterisk = false; +$approved_states = array( 1 => array('reject', 'COM_JOOMGALLERY_COMMON_APPROVED', 'COM_JOOMGALLERY_IMGMAN_REJECT_IMAGE', 'COM_JOOMGALLERY_COMMON_APPROVED', true, 'publish', 'publish'), + 0 => array('approve', 'COM_JOOMGALLERY_COMMON_NOT_APPROVED', 'COM_JOOMGALLERY_IMGMAN_APPROVE_IMAGE', 'COM_JOOMGALLERY_COMMON_NOT_APPROVED', true, 'unpublish', 'unpublish'), + -1 => array('approve', 'COM_JOOMGALLERY_COMMON_REJECTED', 'COM_JOOMGALLERY_IMGMAN_APPROVE_IMAGE', 'COM_JOOMGALLERY_COMMON_REJECTED', true, 'unpublish', 'unpublish')); +if($saveOrder): + $saveOrderingUrl = 'index.php?option='._JOOM_OPTION.'&controller=images&task=saveorder&format=json'; + JHtml::_('sortablelist.sortable', 'imageList', 'adminForm', strtolower($listDirn), $saveOrderingUrl, false, false); +endif; + +JFactory::getDocument()->addScriptDeclaration( + ' + jQuery(document).ready(function() { + jQuery(\'.js-stools-btn-clear\').click(function() { + jQuery(\'#filter_owner\').val(\'\'); + ' . ($this->_config->get('jg_ajaxcategoryselection') ? 'jQuery(\'#filter_category\').val(\'\');' : '') . ' + }); + });' +); +?> + +
    +sidebar)): ?> +
    + sidebar; ?> +
    +
    + +
    + + $this)); + ?> +state->get('filter.inuse') && !$this->get('Total')) : ?> +
    + +
    + + + + + + + + + + + + + + + + + + + + + + +items as $i => $item): + $canEdit = $this->_user->authorise('core.edit', _JOOM_OPTION.'.image.'.$item->id); + $canEditOwn = $this->_user->authorise('core.edit.own', _JOOM_OPTION.'.image.'.$item->id) && $item->owner == $this->_user->get('id'); + $canChange = $this->_user->authorise('core.edit.state', _JOOM_OPTION.'.image.'.$item->id); ?> + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + id); ?> + +
    + published, $i, '', $canChange); ?> + featured($item->featured, $i, '', $canChange); ?> +
    +
    + published && $item->hidden): + echo ''.JText::_('COM_JOOMGALLERY_COMMON_HIDDEN_ASTERISK').''; + $display_hidden_asterisk = true; + endif; ?> +
    +
    + id) : null, true); ?> + + + + escape($item->imgtitle); ?> + + escape($item->imgtitle); ?> + + + escape($item->alias)); ?> + + + approved, $i, '', $canChange, $item->id, $item->owner); ?> + + escape($item->category_name); ?> + + escape($item->access_level); ?> + + owner); ?> + + + + imgauthor; ?> + + imgdate, JText::_('DATE_FORMAT_LC4')); ?> + + hits; ?> + + downloads; ?> + + id; ?> +
    +
    + +pagination->getListFooter(); ?> + +
    + +
    + + + + + +
    + +loadTemplate('reject'); \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/images/tmpl/default_reject.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/images/tmpl/default_reject.php new file mode 100644 index 00000000..c8f48538 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/images/tmpl/default_reject.php @@ -0,0 +1,45 @@ + '.modal-body')); +?> + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/images/tmpl/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/images/tmpl/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/images/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/images/view.html.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/images/view.html.php new file mode 100644 index 00000000..5bca3205 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/images/view.html.php @@ -0,0 +1,121 @@ +items = $this->get('Images'); + $this->state = $this->get('State'); + $this->pagination = $this->get('Pagination'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + $this->addToolbar(); + + $this->sidebar = JHtmlSidebar::render(); + + parent::display($tpl); + } + + /** + * Add the toolbar and toolbar title. + * + * @access protected + * @return void + * + * @since 2.0 + */ + protected function addToolbar() + { + // Get the results for each action + $canDo = JoomHelper::getActions(); + + JToolBarHelper::title(JText::_('COM_JOOMGALLERY_IMGMAN_IMAGE_MANAGER'), 'images'); + + if(($this->_config->get('jg_disableunrequiredchecks') || $canDo->get('joom.upload') || count(JoomHelper::getAuthorisedCategories('joom.upload'))) && $this->pagination->total) + { + JToolbarHelper::addNew('new'); + } + + if(($canDo->get('core.edit') || $canDo->get('core.edit.own')) && $this->pagination->total) + { + JToolbarHelper::editList(); + JToolbarHelper::custom('edit', 'checkbox-partial', 'checkbox-partial', 'JTOOLBAR_BATCH'); + JToolbarHelper::custom('showmove', 'move.png', 'move.png', 'COM_JOOMGALLERY_COMMON_TOOLBAR_MOVE'); + JToolbarHelper::custom('recreate', 'refresh.png', 'refresh.png', 'COM_JOOMGALLERY_COMMON_TOOLBAR_RECREATE'); + JToolbarHelper::divider(); + } + + if($canDo->get('core.edit.state') && $this->pagination->total) + { + JToolbarHelper::publishList('publish', 'COM_JOOMGALLERY_COMMON_PUBLISH'); + JToolbarHelper::unpublishList('unpublish', 'COM_JOOMGALLERY_COMMON_UNPUBLISH'); + JToolbarHelper::custom('approve', 'upload.png', 'upload_f2.png', 'COM_JOOMGALLERY_IMGMAN_TOOLBAR_APPROVE'); + JToolbarHelper::divider(); + } + + //if($canDo->get('core.delete')) + //{ + JToolbarHelper::deleteList('', 'remove'); + //} + + } + + /** + * Returns feature/unfeature buttons for the images list view + * + * @access public + * @param integer $value The featured state. + * @param integer $i The row index + * @param string|array $prefix An optional task prefix or an array of options + * @param boolean $enabled An optional setting for access control on the action. + * @param string $checkbox An optional prefix for checkboxes. + * @return string The HTML markup + * @since 3.3 + */ + public function featured($value, $i, $prefix = '', $enabled = true, $checkbox = 'cb') + { + if (is_array($prefix)) + { + $options = $prefix; + $enabled = array_key_exists('enabled', $options) ? $options['enabled'] : $enabled; + $checkbox = array_key_exists('checkbox', $options) ? $options['checkbox'] : $checkbox; + $prefix = array_key_exists('prefix', $options) ? $options['prefix'] : ''; + } + + $states = array( + 0 => array('feature', '', 'JGLOBAL_TOGGLE_FEATURED', 'COM_JOOMGALLERY_COMMON_UNFEATURED', true, 'unfeatured', 'unfeatured'), + 1 => array('unfeature', '', 'JGLOBAL_TOGGLE_FEATURED', 'COM_JOOMGALLERY_COMMON_FEATURED', true, 'featured', 'featured'), + ); + + return JHtml::_('jgrid.state', $states, $value, $i, $prefix, $enabled, true, $checkbox); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/jupload/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/jupload/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/jupload/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/jupload/tmpl/default.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/jupload/tmpl/default.php new file mode 100644 index 00000000..341fecf4 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/jupload/tmpl/default.php @@ -0,0 +1,82 @@ + +
    +sidebar)): ?> +
    + sidebar; ?> +
    +
    + +
    + +
    +
    +

    + +
    +
    +
    +
    +
    + form->getInput('applet'); ?> +
    +
    +
    +
    + form->getLabel('catid'); ?> +
    + form->getInput('catid'); ?> +
    +
    + _config->get('jg_useorigfilename')): ?> +
    + form->getLabel('imgtitle'); ?> +
    + form->getInput('imgtitle'); ?> +
    +
    + +
    + form->getLabel('imgtext'); ?> +
    + form->getInput('imgtext'); ?> +
    +
    +
    + form->getLabel('imgauthor'); ?> +
    + form->getInput('imgauthor'); ?> +
    +
    +
    + form->getLabel('published'); ?> +
    + form->getInput('published'); ?> +
    +
    +
    + form->getLabel('access'); ?> +
    + form->getInput('access'); ?> +
    +
    + _config->get('jg_delete_original') == 2): ?> +
    + form->getLabel('original_delete'); ?> +
    + form->getInput('original_delete'); ?> +
    +
    + +
    + form->getLabel('create_special_gif'); ?> +
    + form->getInput('create_special_gif'); ?> +
    +
    +
    +
    + +
    + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/jupload/tmpl/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/jupload/tmpl/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/jupload/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/jupload/view.html.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/jupload/view.html.php new file mode 100644 index 00000000..3e0606ac --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/jupload/view.html.php @@ -0,0 +1,48 @@ +form = JForm::getInstance(_JOOM_OPTION.'.jupload', 'jupload'); + $this->form->setFieldAttribute('access', 'default', (int) JFactory::getConfig()->get('access')); + + if($this->_config->get('jg_useorigfilename')) + { + $this->form->setFieldAttribute('imgtitle', 'required', 'false'); + } + + $this->sidebar = JHtmlSidebar::render(); + + parent::display($tpl); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/maintenance/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/maintenance/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/maintenance/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/maintenance/tmpl/default.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/maintenance/tmpl/default.php new file mode 100644 index 00000000..09c726ae --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/maintenance/tmpl/default.php @@ -0,0 +1,37 @@ + +sidebar)): ?> +
    + sidebar; ?> +
    +
    + +
    + +
    + +
    + $this->startOffset)); +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_MAIMAN_TAB_IMAGES').$this->information['images'], 'cpanel-panel-joom-maintenance-db-images'); +echo $this->loadTemplate('dbimages'); +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_MAIMAN_TAB_CATEGORIES').$this->information['categories'], 'cpanel-panel-joom-maintenance-db-categories'); +echo $this->loadTemplate('categories'); +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_MAIMAN_TAB_ORPHANS').$this->information['orphans'], 'cpanel-panel-joom-maintenance-file-images'); +echo $this->loadTemplate('orphans'); +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_MAIMAN_TAB_ORPHANED_FOLDERS').$this->information['folders'], 'cpanel-panel-joom-maintenance-file-folders'); +echo $this->loadTemplate('folders'); +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_COMMAN_COMMENTS_MANAGER'), 'cpanel-panel-joom-maintenance-comments'); +echo $this->loadTemplate('comments'); +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_MAIMAN_FAVOURITES_MANAGER'), 'cpanel-panel-joom-maintenance-favourites'); +echo $this->loadTemplate('favourites'); +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_MAIMAN_TAB_NAMETAGS'), 'cpanel-panel-joom-maintenance-nametags'); +echo $this->loadTemplate('nametags'); +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_MAIMAN_VOTES_MANAGER'), 'cpanel-panel-joom-maintenance-votes'); +echo $this->loadTemplate('votes'); +echo JHtml::_('tabs.panel', JText::_('COM_JOOMGALLERY_MAIMAN_TAB_DATABASE'), 'cpanel-panel-joom-maintenance-database'); +echo $this->loadTemplate('database'); +echo JHtml::_('tabs.end'); +JHtml::_('joomgallery.credits'); ?> +
    \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/maintenance/tmpl/default_categories.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/maintenance/tmpl/default_categories.php new file mode 100644 index 00000000..e8b9288e --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/maintenance/tmpl/default_categories.php @@ -0,0 +1,193 @@ +current_tab != 'categories'): ?> +
    + + +
    +escape($this->state->get('list.ordering')); + $listDirn = $this->escape($this->state->get('list.direction')); ?> +
    +
    + +
    + + +
    + checked): ?> +
    + + pagination->getLimitBox(); ?> +
    + +
    + lists['cat_filter']; ?> +
    +
    + state->get('filter.category'), 'filter_category', 'class="inputbox" size="1" onchange="document.adminForm.submit();"', null, '- ', 'filter'); ?> +
    +
    +
    + + + + + + + + + + + + + + + +checked): + if($n = count($this->items)): ?> + + + + + + + + + + + + + + +checked): + $k = 0; + for($i = 0; $i < $n; $i++): + $row = &$this->items[$i]; ?> + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + +
    + pagination->getListFooter(); ?> +
    + +
    + +
    + +
    + +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    + id); ?> + + + escape($row->title); ?> + + +thumb): ?> + tick(); ?> + + cross(); + echo $row->thumborphan ? $this->correct('addorphanedfolder', $row->thumborphan, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_ADD_ORPHANED_FOLDER')) : ''; + echo $this->correct('create', $row->id, JText::_('COM_JOOMGALLERY_MAIMAN_OF_CREATE_EMPTY_FOLDER').'::'.JText::_('COM_JOOMGALLERY_MAIMAN_OF_CREATE_EMPTY_FOLDER_NOTE'), false, '&type=thumb'); ?> + + +img): ?> + tick(); ?> + + cross(); + echo $row->imgorphan ? $this->correct('addorphanedfolder', $row->imgorphan, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_ADD_ORPHANED_FOLDER')) : ''; + echo $this->correct('create', $row->id, JText::_('COM_JOOMGALLERY_MAIMAN_OF_CREATE_EMPTY_FOLDER').'::'.JText::_('COM_JOOMGALLERY_MAIMAN_OF_CREATE_EMPTY_FOLDER_NOTE'), false, '&type=img'); ?> + + +orig): ?> + tick(); ?> + + cross(); + echo $row->origorphan ? $this->correct('addorphanedfolder', $row->origorphan, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_ADD_ORPHAN')) : ''; + echo $this->correct('create', $row->id, JText::_('COM_JOOMGALLERY_MAIMAN_OF_CREATE_EMPTY_FOLDER').'::'.JText::_('COM_JOOMGALLERY_MAIMAN_OF_CREATE_EMPTY_FOLDER_NOTE'), false, '&type=orig'); ?> + + +owner != -1): ?> + owner); echo $this->tick(); ?> + + cross(); + echo $this->correct('newcategoryuser', null, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_SET_NEW_USER'), 'javascript:joom_selectnewuser('.$i.')'); ?> +
    + +
    +catid != -1): ?> + category/*JHtml::_('joomgallery.categorypath', $row->refid, false)*/; echo $this->tick(); ?> + + cross(); ?> + + + refid; ?> +
    +
    +
    + + lists['cat_jobs']; ?> +
    + +
    +
    +
    + + + + + + + + + + <?php echo JText::_('COM_JOOMGALLERY_MAIMAN_APPLY'); ?> + +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    + +
    +
    + + + +
    +
    \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/maintenance/tmpl/default_database.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/maintenance/tmpl/default_database.php new file mode 100644 index 00000000..5a066b19 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/maintenance/tmpl/default_database.php @@ -0,0 +1,16 @@ + +
    +
    +
    +
    + +
    +
    + +
    + + + +
    +
    +
    \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/maintenance/tmpl/default_dbimages.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/maintenance/tmpl/default_dbimages.php new file mode 100644 index 00000000..3cefa0f7 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/maintenance/tmpl/default_dbimages.php @@ -0,0 +1,234 @@ +current_tab == 'orphans' || $this->current_tab == 'categories' || $this->current_tab == 'folders'): ?> +
    + + +
    +escape($this->state->get('list.ordering')); + $listDirn = $this->escape($this->state->get('list.direction')); ?> +
    +
    + +
    + + +
    + checked): ?> +
    + + pagination->getLimitBox(); ?> +
    + +
    + lists['img_filter']; ?> +
    +
    + state->get('filter.category'), 'filter_category', 'class="inputbox" size="1" onchange="document.adminForm.submit();"', null, '- ', 'filter'); ?> +
    +
    +
    + + + + + + + + + + + + + + + + +checked): + if($n = count($this->items)): ?> + + + + + + + + + + + + + + +checked): + $k = 0; + for($i = 0; $i < $n; $i++): + $row = &$this->items[$i]; ?> + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + +
    + pagination->getListFooter(); ?> +
    + +
    + +
    +state->get('check_originals')): ?> +
    + +
    + +

    + +

    + +
    + state->get('check_originals', 1) ? ' checked="checked"' : ''; ?> value="0" name="check_originals"> + + state->get('check_originals', 1) ? ' checked="checked"' : ''; ?> value="1" name="check_originals"> + +
    +
    +
    +

    +
    +
    + +
    +

    + +

    + +
    + state->get('check_originals', 1) ? ' checked="checked"' : ''; ?> value="0" name="check_originals"> + + state->get('check_originals', 1) ? ' checked="checked"' : ''; ?> value="1" name="check_originals"> + +
    +
    +
    +

    +
    + +
    +
    + id); ?> + +thumb): + $link = 'index.php?option='._JOOM_OPTION.'&controller=images&task=edit&cid='.$row->refid; ?> + _ambit->getImgObject($row->refid), 'jg_minithumb', 'href="'.$link); ?> + +   + + + + title; ?> + + +thumb): ?> + tick(); ?> + + cross(); + echo $row->thumborphan ? $this->correct('addorphan', $row->thumborphan, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_ADD_ORPHAN')) : ''; + if($row->orig): + echo $this->correct('recreate', $row->id, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_RECREATE_FROM_ORIG'), false, '&type=thumb'); + else: + if($row->img): + echo $this->correct('recreate', $row->id, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_RECREATE_FROM_IMG')); + endif; + endif; ?> + + +img): ?> + tick(); ?> + + cross(); + echo $row->imgorphan ? $this->correct('addorphan', $row->imgorphan, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_ADD_ORPHAN')) : ''; + if($row->orig): + echo $this->correct('recreate', $row->id, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_RECREATE_FROM_ORIG'), false, '&type=img'); + endif; ?> + + +orig): ?> + tick(); ?> + + cross(); + echo $row->origorphan ? $this->correct('addorphan', $row->origorphan, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_ADD_ORPHAN')) : ''; ?> + + +owner != -1): ?> + owner); echo $this->tick(); ?> + + cross(); ?> + correct('newuser', null, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_SET_NEW_USER'), 'javascript:joom_selectnewuser('.$i.')'); ?> +
    + +
    +catid != -1): ?> + category/*JHtml::_('joomgallery.categorypath', $row->catid)*/; echo $this->tick(); ?> + + cross(); ?> + + + refid; ?> +
    +
    +
    + + lists['img_jobs']; ?> +
    + +
    +
    +
    + + + + + + + + + + + +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    + +
    +
    + + + +
    +
    \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/maintenance/tmpl/default_folders.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/maintenance/tmpl/default_folders.php new file mode 100644 index 00000000..5e3245c1 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/maintenance/tmpl/default_folders.php @@ -0,0 +1,154 @@ +current_tab != 'folders'): ?> +
    + + +
    +escape($this->state->get('list.ordering')); + $listDirn = $this->escape($this->state->get('list.direction')); ?> +
    +
    + +
    + + +
    + checked): ?> +
    + + pagination->getLimitBox(); ?> +
    + +
    + lists['folder_proposal']; ?> +
    +
    +
    + + + + + + + + + + + + +checked): + if($n = count($this->items)): ?> + + + + + + + + + + + + + + +checked): + $k = 0; + for($i = 0; $i < $n; $i++): + $row = &$this->items[$i]; ?> + + + + + + + + + +
    + + + + + + + +
    + pagination->getListFooter(); ?> +
    + +
    + +
    + +
    + +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    + id); ?> + + type == 'unknown' ? $this->warning(JText::_('COM_JOOMGALLERY_MAIMAN_UNKNOWN_FILE_TYPE'), JText::_('COM_JOOMGALLERY_MAIMAN_UNKNOWN_FILE_TYPE_LONG')) : ''; ?> fullpath; ?> + +refid): ?> + + + title; ?> + + + correct('addorphanedfolder', $row->id, JText::_('COM_JOOMGALLERY_MAIMAN_OF_ADD_ORPHANED_FOLDER_TO_CATEGORY'), false, '&tab=folders'); ?> + + cross('COM_JOOMGALLERY_MAIMAN_NO_PROPOSAL'); ?> + correct('deleteorphanedfolder', 0, JText::_('COM_JOOMGALLERY_MAIMAN_OF_DELETE_THIS_ORPHANED_FOLDER'), 'javascript:listItemTask(\'cb'.$i.'\', \'deleteorphanedfolder\');', '&tab=folders'); ?> + + + id; ?> +
    +
    +
    + + lists['folder_jobs']; ?> +
    + +
    +
    +
    + + + + + + + + +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    + +
    +
    + + + +
    +
    \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/maintenance/tmpl/default_orphans.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/maintenance/tmpl/default_orphans.php new file mode 100644 index 00000000..7ae31e76 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/maintenance/tmpl/default_orphans.php @@ -0,0 +1,157 @@ +current_tab != 'orphans'): ?> +
    + + +
    +escape($this->state->get('list.ordering')); + $listDirn = $this->escape($this->state->get('list.direction')); ?> +
    +
    + +
    + + +
    + checked): ?> +
    + + pagination->getLimitBox(); ?> +
    + +
    + lists['orphan_filter']; ?> +
    +
    + lists['orphan_proposal']; ?> +
    +
    +
    + + + + + + + + + + + + +checked): + if($n = count($this->items)): ?> + + + + + + + + + + + + + + +checked): + $k = 0; + for($i = 0; $i < $n; $i++): + $row = &$this->items[$i]; ?> + + + + + + + + + +
    + + + + + + + + + +
    + pagination->getListFooter(); ?> +
    + +
    + +
    + +
    + +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    + id); ?> + + type == 'unknown' ? $this->warning(JText::_('COM_JOOMGALLERY_MAIMAN_UNKNOWN_FILE_TYPE'), JText::_('COM_JOOMGALLERY_MAIMAN_UNKNOWN_FILE_TYPE_LONG')) : ''; ?> fullpath; ?> + + type != 'unknown'): + echo JText::_('COM_JOOMGALLERY_MAIMAN_TYPE_'.strtoupper($row->type)); + else: + #jimport('joomla.filesystem.file'); + echo JText::sprintf('COM_JOOMGALLERY_MAIMAN_TYPE_UNKNOWN_VAL'/*, JFile::getExt($row->fullpath)*/); + endif; ?> + +refid): ?> + + + title; ?> + + + correct('addorphan', $row->id, JText::_('COM_JOOMGALLERY_MAIMAN_ADD_ORPHAN_TO_IMAGE')); ?> + + cross('COM_JOOMGALLERY_MAIMAN_NO_PROPOSAL'); ?> + correct('deleteorphan', 0, JText::_('COM_JOOMGALLERY_MAIMAN_DELETE_THIS_ORPHAN'), 'javascript:listItemTask(\'cb'.$i.'\', \'deleteorphan\');'); ?> + + + id; ?> +
    +
    +
    + + lists['orphan_jobs']; ?> +
    + +
    +
    +
    + + + + + + + + +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    + +
    +
    + + + +
    +
    \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/maintenance/tmpl/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/maintenance/tmpl/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/maintenance/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/maintenance/view.html.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/maintenance/view.html.php new file mode 100644 index 00000000..ff8be0a5 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/maintenance/view.html.php @@ -0,0 +1,269 @@ +_doc->addStyleDeclaration(' .icon-32-refresh { + background-image:url(templates/khepri/images/toolbar/icon-32-refresh.png); + }'); + + $lists = array(); + + jimport('joomla.html.pane'); + $tabs = array('images' => 0, + 'categories' => 1, + 'orphans' => 2, + 'folders' => 3, + 'comments' => 4, + 'favourites' => 5, + 'nametags' => 6, + 'votes' => 7, + 'database' => 8 + ); + $tab = $this->_mainframe->getUserStateFromRequest('joom.maintenance.tab', 'tab', 'images', 'cmd'); + if(!$tab || !isset($tabs[$tab])) + { + $tab = 'images'; + } + + $checked = $this->_mainframe->getUserState('joom.maintenance.checked'); + + $state = $this->get('State'); + + switch($tab) + { + case 'categories': + // Select list of the batch jobs for the categories + $b_options = array(); + $b_options[] = JHTML::_('select.option', '', JText::_('COM_JOOMGALLERY_MAIMAN_SELECT_JOB')); + $b_options[] = JHTML::_('select.option', 'setuser', JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_SET_NEW_USER')); + $b_options[] = JHTML::_('select.option', 'addorphanedfolders', JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_ADD_ORPHANED_FOLDERS')); + $b_options[] = JHTML::_('select.option', 'create', JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_CREATE_FOLDERS')); + $b_options[] = JHTML::_('select.option', 'removecategory', JText::_('COM_JOOMGALLERY_MAIMAN_CT_OPTION_REMOVE_CATEGORIES')); + $lists['cat_jobs'] = JHTML::_( 'select.genericlist', $b_options, 'job', + 'class="inputbox" size="1" onchange="joom_selectbatchjob(this.value);"', + 'value', 'text'); + + $f_options = array(); + $f_options[] = JHTML::_('select.option', 0, JText::_('COM_JOOMGALLERY_COMMON_OPTION_ALL_CATEGORIES')); + $f_options[] = JHTML::_('select.option', 1, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_MISSING_THUMB_FOLDER_ONLY')); + $f_options[] = JHTML::_('select.option', 2, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_MISSING_IMG_FOLDER_ONLY')); + $f_options[] = JHTML::_('select.option', 3, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_MISSING_ORIG_FOLDER_ONLY')); + $f_options[] = JHTML::_('select.option', 4, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_MISSING_USER_ONLY')); + $f_options[] = JHTML::_('select.option', 5, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_MISSING_PARENT_CATEGORY_ONLY')); + $lists['cat_filter'] = JHTML::_( 'select.genericlist', $f_options, 'filter_type', + 'class="inputbox" size="1" onchange="document.adminForm.submit();"', + 'value', 'text', $state->get('filter.type')); + + if(!is_null($checked)) + { + // Get data from the model + $items = $this->get('Categories'); + } + break; + case 'orphans': + // Select list of the batch jobs for the orphans + $b_options = array(); + $b_options[] = JHTML::_('select.option', '', JText::_('COM_JOOMGALLERY_MAIMAN_SELECT_JOB')); + $b_options[] = JHTML::_('select.option', 'addorphan', JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_ADD_ORPHANS')); + $b_options[] = JHTML::_('select.option', 'applysuggestions', JText::_('COM_JOOMGALLERY_MAIMAN_APPLY_SUGGESTIONS')); + $b_options[] = JHTML::_('select.option', 'deleteorphan', JText::_('COM_JOOMGALLERY_MAIMAN_REMOVE_ORPHANS')); + $lists['orphan_jobs'] = JHTML::_( 'select.genericlist', $b_options, 'job', + 'class="inputbox" size="1"', + 'value', 'text'); + + $p_options = array(); + $p_options[] = JHTML::_('select.option', 0, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_ALL_FILES')); + $p_options[] = JHTML::_('select.option', 1, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_PROPOSAL_AVAILABLE')); + $p_options[] = JHTML::_('select.option', 2, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_NO_PROPOSAL_AVAILABLE')); + $lists['orphan_proposal'] = JHTML::_( 'select.genericlist', $p_options, 'filter_proposal', + 'class="inputbox" size="1" onchange="document.adminForm.submit();"', + 'value', 'text', $state->get('filter.proposal')); + + $f_options = array(); + $f_options[] = JHTML::_('select.option', 0, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_ALL_FILES')); + $f_options[] = JHTML::_('select.option', 1, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_TYPE_THUMB_ONLY')); + $f_options[] = JHTML::_('select.option', 2, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_TYPE_IMG_ONLY')); + $f_options[] = JHTML::_('select.option', 3, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_TYPE_ORIG_ONLY')); + $f_options[] = JHTML::_('select.option', 4, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_TYPE_UNKNOWN_ONLY')); + $lists['orphan_filter'] = JHTML::_( 'select.genericlist', $f_options, 'filter_type', + 'class="inputbox" size="1" onchange="document.adminForm.submit();"', + 'value', 'text', $state->get('filter.type')); + + if(!is_null($checked)) + { + // Get data from the model + $items = $this->get('Orphans'); + } + break; + case 'folders': + // Select list of the batch jobs for the orphans + $b_options = array(); + $b_options[] = JHTML::_('select.option', '', JText::_('COM_JOOMGALLERY_MAIMAN_SELECT_JOB')); + $b_options[] = JHTML::_('select.option', 'addorphanedfolder', JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_ADD_ORPHANED_FOLDERS')); + $b_options[] = JHTML::_('select.option', 'applyfoldersuggestions', JText::_('COM_JOOMGALLERY_MAIMAN_APPLY_SUGGESTIONS')); + $b_options[] = JHTML::_('select.option', 'deleteorphanedfolder', JText::_('COM_JOOMGALLERY_MAIMAN_OF_OPTION_REMOVE_ORPHANED_FOLDERS')); + $lists['folder_jobs'] = JHTML::_( 'select.genericlist', $b_options, 'job', + 'class="inputbox" size="1"', + 'value', 'text'); + + $p_options = array(); + $p_options[] = JHTML::_('select.option', 0, JText::_('COM_JOOMGALLERY_MAIMAN_OF_OPTION_ALL_FOLDERS')); + $p_options[] = JHTML::_('select.option', 1, JText::_('COM_JOOMGALLERY_MAIMAN_OF_OPTION_PROPOSAL_AVAILABLE_FOLDERS')); + $p_options[] = JHTML::_('select.option', 2, JText::_('COM_JOOMGALLERY_MAIMAN_OF_OPTION_NO_PROPOSAL_AVAILABLE_FOLDERS')); + $lists['folder_proposal'] = JHTML::_( 'select.genericlist', $p_options, 'filter_proposal', + 'class="inputbox" size="1" onchange="document.adminForm.submit();"', + 'value', 'text', $state->get('filter.proposal')); + + $f_options = array(); + $f_options[] = JHTML::_('select.option', 0, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_ALL_FILES')); + $f_options[] = JHTML::_('select.option', 1, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_TYPE_THUMB_ONLY')); + $f_options[] = JHTML::_('select.option', 2, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_TYPE_IMG_ONLY')); + $f_options[] = JHTML::_('select.option', 3, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_TYPE_ORIG_ONLY')); + $f_options[] = JHTML::_('select.option', 4, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_TYPE_UNKNOWN_ONLY')); + $lists['folder_filter'] = JHTML::_( 'select.genericlist', $f_options, 'filter_type', + 'class="inputbox" size="1" onchange="document.adminForm.submit();"', + 'value', 'text', $state->get('filter.type')); + + if(!is_null($checked)) + { + // Get data from the model + $items = $this->get('OrphanedFolders'); + } + break; + default: + // Select list of the batch jobs for the images + $b_options = array(); + $b_options[] = JHTML::_('select.option', '', JText::_('COM_JOOMGALLERY_MAIMAN_SELECT_JOB')); + $b_options[] = JHTML::_('select.option', 'setuser', JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_SET_NEW_USER')); + $b_options[] = JHTML::_('select.option', 'addorphans', JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_ADD_ORPHANS')); + $b_options[] = JHTML::_('select.option', 'recreate', JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_RECREATE')); + $b_options[] = JHTML::_('select.option', 'remove', JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_REMOVE_IMAGES')); + $lists['img_jobs'] = JHTML::_( 'select.genericlist', $b_options, 'job', + 'class="inputbox" size="1" onchange="joom_selectbatchjob(this.value);"', + 'value', 'text'); + + $f_options = array(); + $f_options[] = JHTML::_('select.option', 0, JText::_('COM_JOOMGALLERY_COMMON_OPTION_ALL_IMAGES')); + $f_options[] = JHTML::_('select.option', 1, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_MISSING_THUMB_ONLY')); + $f_options[] = JHTML::_('select.option', 2, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_MISSING_IMG_ONLY')); + $f_options[] = JHTML::_('select.option', 3, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_MISSING_ORIG_ONLY')); + $f_options[] = JHTML::_('select.option', 4, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_MISSING_USER_ONLY')); + $f_options[] = JHTML::_('select.option', 5, JText::_('COM_JOOMGALLERY_MAIMAN_OPTION_MISSING_CATEGORY_ONLY')); + $lists['img_filter'] = JHTML::_( 'select.genericlist', $f_options, 'filter_type', + 'class="inputbox" size="1" onchange="document.adminForm.submit();"', + 'value', 'text', $state->get('filter.type')); + + if(!is_null($checked)) + { + // Get data from the model + $items = $this->get('Images'); + } + break; + } + + if(!is_null($checked)) + { + $this->items = $items; + $this->pagination = $this->get('Pagination'); + + if($state->get('filter.inuse') && !$this->get('Total')) + { + $this->_mainframe->enqueueMessage(JText::_('COM_JOOMGALLERY_MAIMAN_MSG_NO_ITEMS_FOUND_MATCHING_YOUR_QUERY')); + } + } + + $information = $this->get('Information'); + $warning = 'Warning'; + foreach($information as $key => $found) + { + if($found) + { + $information[$key] = ' '.$warning; + } + else + { + $information[$key] = ''; + } + } + + $this->assignRef('current_tab', $tab); + $this->assignRef('startOffset', $tabs[$tab]); + $this->assignRef('checked', $checked); + $this->assignRef('information', $information); + $this->assignRef('lists', $lists); + $this->assignRef('state', $state); + + $this->_doc->addScript($this->_ambit->getScript('maintenance.js')); + + // Language + JText::script('COM_JOOMGALLERY_MAIMAN_ALERT_RESET_VOTES_CONFIRM'); + JText::script('COM_JOOMGALLERY_MAIMAN_CM_ALERT_RESET_COMMENTS_CONFIRM'); + JText::script('COM_JOOMGALLERY_MAIMAN_FV_ALERT_RESET_FAVOURITES_CONFIRM'); + JText::script('COM_JOOMGALLERY_MAIMAN_NT_ALERT_RESET_NAMETAGS_CONFIRM'); + + $this->sidebar = JHtmlSidebar::render(); + + parent::display($tpl); + } + + function cross($title = 'COM_JOOMGALLERY_MAIMAN_MISSING') + { + return ''; + } + + function tick($title = 'COM_JOOMGALLERY_MAIMAN_AVAILABLE') + { + return ''; + } + + function correct($task, $id, $title = 'Apply', $js = false, $extra = null) + { + if($js) + { + $link = $js; + } + else + { + $link = 'index.php?option='._JOOM_OPTION.'&controller=maintenance&task='.$task.'&cid='.$id.$extra; + } + + return ' + '.$title.''; + } + + function warning($title, $text) + { + return 'Warning'; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/migration/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/migration/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/migration/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/migration/tmpl/default.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/migration/tmpl/default.php new file mode 100644 index 00000000..baebe816 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/migration/tmpl/default.php @@ -0,0 +1,32 @@ + +sidebar)): ?> +
    + sidebar; ?> +
    +
    + +
    + +
    + files) ? 'COM_JOOMGALLERY_MIGMAN_NOTE' : 'COM_JOOMGALLERY_MIGMAN_NOTE_NO_SCRIPTS'); ?> +
    + output; ?> + +files as $file): + require_once $file; + $class = 'JoomMigrate'.substr(basename($file), 7, -4); + if(class_exists($class)) + { + $migration = new $class(); + echo $migration->getForm(); + } + endforeach; +?> +
    + +
    diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/migration/tmpl/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/migration/tmpl/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/migration/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/migration/view.html.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/migration/view.html.php new file mode 100644 index 00000000..f4185966 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/migration/view.html.php @@ -0,0 +1,53 @@ +sidebar = JHtmlSidebar::render(); + + $this->output = $this->_mainframe->getUserState('joom.migration.output', null); + $this->_mainframe->setUserState('joom.migration.output', null); + + $this->files = JFolder::files(JPATH_COMPONENT.'/helpers/migration', '.php$', false, true); + + parent::display($tpl); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/mini/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/mini/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/mini/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/mini/tmpl/default.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/mini/tmpl/default.php new file mode 100644 index 00000000..98b590e3 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/mini/tmpl/default.php @@ -0,0 +1,109 @@ +get('debug'); ?> + + + + + MiniJoom + + + + + + isRTL()): ?> + + + + + + + + + + + + _config->get('jg_ajaxcategoryselection')): ?> + + + + + + + + + + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/mini/tmpl/default_categories.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/mini/tmpl/default_categories.php new file mode 100644 index 00000000..fc2d29aa --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/mini/tmpl/default_categories.php @@ -0,0 +1,61 @@ + +
    +
    + categories_form->getLabel('category_mode'); ?> +
    + categories_form->getInput('category_mode'); ?> +
    +
    +
    +
    + categories_form->getLabel('category_limit'); ?> +
    + categories_form->getInput('category_limit'); ?> +
    +
    +
    + categories_form->getLabel('category_columns'); ?> +
    + categories_form->getInput('category_columns'); ?> +
    +
    +
    + categories_form->getLabel('category_ordering'); ?> +
    + categories_form->getInput('category_ordering'); ?> +
    +
    +
    + categories_form->getLabel('category_linkedtext'); ?> +
    + categories_form->getInput('category_linkedtext'); ?> +
    +
    +
    +
    + categories_form->getLabel('category_catid'); ?> +
    + categories_form->getInput('category_catid'); ?> +
    +
    +
    + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/mini/tmpl/default_createcategory.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/mini/tmpl/default_createcategory.php new file mode 100644 index 00000000..7c2c8959 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/mini/tmpl/default_createcategory.php @@ -0,0 +1,32 @@ +_mainframe->isSite()): + $action = JRoute::_('index.php?option='._JOOM_OPTION.'&task=category.save&tmpl=component&redirect='.base64_encode('index.php?option='._JOOM_OPTION.'&view=mini&format=raw')); +else: + $action = JRoute::_('index.php?option='._JOOM_OPTION.'&controller=categories&task=save&tmpl=component&redirect='.base64_encode('index.php?option='._JOOM_OPTION.'&view=mini&format=raw')); +endif; ?> +
    +
    + category_form->getLabel('name'); ?> +
    + category_form->getInput('name'); ?> +
    +
    +
    + category_form->getLabel('parent_id'); ?> +
    + parent_categories ? $this->parent_categories : $this->category_form->getInput('parent_id'); ?> +
    +
    +
    + category_form->getLabel('published'); ?> +
    + category_form->getInput('published'); ?> +
    +
    +
    +
    + +
    + +
    +
    \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/mini/tmpl/default_images.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/mini/tmpl/default_images.php new file mode 100644 index 00000000..16815cba --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/mini/tmpl/default_images.php @@ -0,0 +1,110 @@ + + $this->extended > 0 ? 'param-page-images-options' : 'param-page-images-search', 'parent' => 'joomgallery-images-sliders')); + if($this->extended > 0): + echo JHtml::_('bootstrap.addslide', 'joomgallery-images-sliders', JText::_('COM_JOOMGALLERY_MINI_EXTENDED'), 'param-page-images-options'); ?> + +
    +
    + images_form->getLabel('type'); ?> +
    + images_form->getInput('type'); ?> +
    +
    +
    + images_form->getLabel('position'); ?> +
    + images_form->getInput('position'); ?> +
    +
    +
    + images_form->getLabel('linked'); ?> +
    + images_form->getInput('linked'); ?> +
    +
    +
    + images_form->getLabel('linked_type'); ?> +
    + images_form->getInput('linked_type'); ?> +
    +
    +
    + images_form->getLabel('alttext'); ?> +
    + images_form->getInput('alttext'); ?> +
    +
    +
    + images_form->getLabel('class'); ?> +
    + images_form->getInput('class'); ?> +
    +
    +
    + images_form->getLabel('linkedtext'); ?> +
    + images_form->getInput('linkedtext'); ?> +
    +
    +
    + + +
    +
    + +
    +
    + +
    +
    + + +
    +
    + lists['limit']; ?> +
    +
    +extended != -1): ?> +
    + + lists['image_categories']; ?> +
    + +
    +
    +images)): ?> +
    + +
    +images as $row): ?> + + +
    +
    + +
    +
    +
    + escape($this->image->imgtitle); ?> +
    +catid): ?> +
    + escape($this->image->name); ?> +
    + +
    +
    \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/mini/tmpl/default_pagination.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/mini/tmpl/default_pagination.php new file mode 100644 index 00000000..8d65a1d6 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/mini/tmpl/default_pagination.php @@ -0,0 +1,50 @@ + +
    +total < 1): ?> + +total == 1): ?> + +total > 1): ?> + total); ?> + +
    +totalpages > 1): ?> + + +
    +
    + upload_form->getLabel('catid'); ?> +
    + upload_categories ? $this->upload_categories : $this->upload_form->getInput('catid'); ?> +
    +
    + editFilename): ?> +
    + upload_form->getLabel('generictitle'); ?> +
    + upload_form->getInput('generictitle'); ?> +
    +
    +
    + upload_form->getLabel('imgtitle'); ?> +
    + upload_form->getInput('imgtitle'); ?> +
    +
    + +
    + upload_form->getLabel('published'); ?> +
    + upload_form->getInput('published'); ?> +
    +
    + delete_original): ?> +
    + upload_form->getLabel('original_delete'); ?> +
    + upload_form->getInput('original_delete'); ?> +
    +
    + +
    + upload_form->getLabel('create_special_gif'); ?> +
    + upload_form->getInput('create_special_gif'); ?> +
    +
    +
    +
    + upload_form->getInput('ajaxupload'); ?> +
    +
    + + +
    \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/mini/tmpl/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/mini/tmpl/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/mini/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/mini/view.json.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/mini/view.json.php new file mode 100644 index 00000000..0cc8f281 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/mini/view.json.php @@ -0,0 +1,124 @@ +_mainframe->getUserStateFromRequest('joom.mini.e_name', 'e_name', 'text', 'string'); + + $catid = $this->_mainframe->getUserStateFromRequest('joom.mini.catid', 'catid', 0, 'int'); + $this->assignRef('catid', $catid); + $this->prefix = $this->_mainframe->getUserStateFromRequest('joom.mini.prefix', 'prefix', 'joom', 'cmd'); + + // Pagination + $total = $this->get('TotalImages'); + + // Calculation of the number of total pages + $limit = $this->_mainframe->getUserStateFromRequest('joom.mini.limit', 'limit', 30, 'int'); + if(!$limit) + { + $totalpages = 1; + } + else + { + $totalpages = floor($total / $limit); + $offcut = $total % $limit; + if($offcut > 0) + { + $totalpages++; + } + } + + $totalimages = $total; + $total = number_format($total, 0, ',', '.'); + + // Get the current page + $page = JRequest::getInt('page', 0); + if($page > $totalpages) + { + $page = $totalpages; + } + if($page < 1) + { + $page = 1; + } + + // Limitstart + $limitstart = ($page - 1) * $limit; + JRequest::setVar('limitstart', $limitstart); + + if($total <= $limit) + { + $limitstart = 0; + JRequest::setVar('limitstart', $limitstart); + } + + JRequest::setVar('limit', $limit); + + require_once JPATH_COMPONENT_ADMINISTRATOR.'/helpers/pagination.php'; + $onclick = 'javascript:ajaxRequest(\'index.php?option='._JOOM_OPTION.'&view=mini&format=json\', %u); return false;'; + $this->pagination = new JoomPagination($totalimages, $limitstart, $limit, '', null, $onclick); + + $images = $this->get('Images'); + + foreach($images as $key => $image) + { + $image->thumb_src = null; + $thumb = $this->_ambit->getImg('thumb_path', $image); + if($image->imgthumbname && is_file($thumb)) + { + $imginfo = getimagesize($thumb); + $image->thumb_src = $this->_ambit->getImg('thumb_url', $image); + $image->thumb_width = $imginfo[0]; + $image->thumb_height = $imginfo[1]; + $this->image = $image; + $overlib = $this->loadTemplate('overlib'); + $image->overlib = str_replace(array("\r\n", "\r", "\n"), '', htmlspecialchars($overlib, ENT_QUOTES, 'UTF-8')); + } + + $images[$key] = $image; + } + + $object = $this->_mainframe->getUserStateFromRequest('joom.mini.object', 'object', '', 'cmd'); + + $this->assignRef('images', $images); + $this->assignRef('total', $total); + $this->assignRef('totalpages', $totalpages); + $this->assignRef('page', $page); + $this->assignRef('object', $object); + $this->assignRef('e_name', $e_name); + + $output = array(); + $output['minis'] = $this->loadTemplate('minis'); + $output['pagination'] = $this->loadTemplate('pagination'); + + echo json_encode($output); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/mini/view.raw.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/mini/view.raw.php new file mode 100644 index 00000000..d8a6febd --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/mini/view.raw.php @@ -0,0 +1,325 @@ +page = 1; + $this->e_name = $this->_mainframe->getUserStateFromRequest('joom.mini.e_name', 'e_name', 'text', 'string'); + $this->images_fields = array('type', 'position', 'linked', 'linked_type', 'alttext', 'class', 'linkedtext'); + + $this->extended = $this->_mainframe->getUserStateFromRequest('joom.mini.extended', 'extended', 1, 'int'); + $this->upload_catid = $this->_mainframe->input->getInt('upload_category'); + $this->prefix = $this->_mainframe->getUserStateFromRequest('joom.mini.prefix', 'prefix', 'joom', 'cmd'); + + // Decide which tabs have to be displayed + $this->tabs = array('images' => true); + if($this->extended > 0) + { + $this->tabs = array('images' => true, 'categories' => true, 'upload' => true, 'createcategory' => true); + } + + if($this->upload_catid) + { + $this->tabs = array('upload' => true); + } + + // Images tab + if(isset($this->tabs['images'])) + { + // Also display the options for inserting images into articles + if($this->extended > 0) + { + $plugin = JPluginHelper::getPlugin('content', 'joomplu'); + if(!$this->upload_catid && !count($plugin)) + { + $this->_mainframe->enqueueMessage(JText::_('COM_JOOMGALLERY_MINI_MSG_NOT_INSTALLED_OR_ACTIVATED'), 'notice'); + $params = ''; + } + else + { + $params = $plugin->params; + } + + // Load plugin parameters + $this->params = new JRegistry(); + $this->params->loadString($params); + + $this->images_form = JForm::getInstance(_JOOM_OPTION.'.mini.images', 'mini.images'); + + $fields_default_values = array('type' => 'thumb', 'position' => '', 'linked' => 0, 'linked_type' => 'orig', 'alttext' => '', 'class' => '', 'linkedtext' => ''); + foreach($this->images_fields as $field) + { + $this->images_form->setFieldAttribute($field, 'default', $this->params->get('default_'.$field, $fields_default_values[$field])); + } + + // Hidden images + $this->_mainframe->setUserState('joom.mini.showhidden', $this->params->get('showhidden')); + } + + // Pagination + $this->total = $this->get('TotalImages'); + + // Calculation of the number of total pages + $limit = $this->_mainframe->getUserStateFromRequest('joom.mini.limit', 'limit', 30, 'int'); + if(!$limit) + { + $this->totalpages = 1; + } + else + { + $this->totalpages = floor($this->total / $limit); + $offcut = $this->total % $limit; + if($offcut > 0) + { + $this->totalpages++; + } + } + + $totalimages = $this->total; + $this->total = number_format($this->total, 0, JText::_('COM_JOOMGALLERY_COMMON_DECIMAL_SEPARATOR'), JText::_('COM_JOOMGALLERY_COMMON_THOUSANDS_SEPARATOR')); + + // Get the current page + $this->page = JRequest::getInt('page', 0); + if($this->page > $this->totalpages) + { + $this->page = $this->totalpages; + } + if($this->page < 1) + { + $this->page = 1; + } + + // Limitstart + $limitstart = ($this->page - 1) * $limit; + JRequest::setVar('limitstart', $limitstart); + + if($this->total <= $limit) + { + $limitstart = 0; + JRequest::setVar('limitstart', $limitstart); + } + + JRequest::setVar('limit', $limit); + + require_once JPATH_COMPONENT_ADMINISTRATOR.'/helpers/pagination.php'; + $onclick = 'javascript:ajaxRequest(\'index.php?option='._JOOM_OPTION.'&view=mini&format=json\', %u); return false;'; + $this->pagination = new JoomPagination($totalimages, $limitstart, $limit, '', null, $onclick); + + $this->images = $this->get('Images'); + + $this->catid = $this->_mainframe->getUserStateFromRequest('joom.mini.catid', 'catid', 0, 'int'); + + foreach($this->images as $key => $image) + { + $image->thumb_src = null; + $thumb = $this->_ambit->getImg('thumb_path', $image); + if($image->imgthumbname && is_file($thumb)) + { + $imginfo = getimagesize($thumb); + $image->thumb_src = $this->_ambit->getImg('thumb_url', $image); + $image->thumb_width = $imginfo[0]; + $image->thumb_height = $imginfo[1]; + $this->image = $image; + $overlib = $this->loadTemplate('overlib'); + $image->overlib = str_replace(array("\r\n", "\r", "\n"), '', htmlspecialchars($overlib, ENT_QUOTES, 'UTF-8')); + } + + $this->images[$key] = $image; + } + + // Limit Box + $limits = array(); + + // Create the option list + for($i = 5; $i <= 30; $i += 5) + { + $limits[] = JHtml::_('select.option', $i); + } + $limits[] = JHtml::_('select.option', '50'); + $limits[] = JHtml::_('select.option', '100'); + $limits[] = JHtml::_('select.option', '0', JText::_('JALL')); + + $url = 'index.php?option='._JOOM_OPTION.'&view=mini&format=json'; + $this->lists = array(); + $this->lists['limit'] = JHtml::_('select.genericlist', $limits, 'limit', 'class="inputbox input-mini" size="1" onchange="javascript:ajaxRequest(\''.$url.'\', 0, \'limit=\' + this[this.selectedIndex].value)"', 'value', 'text', $limit); + $this->lists['image_categories'] = JHtml::_('joomselect.categorylist', $this->catid, 'catid', 'onchange="javascript:ajaxRequest(\''.$url.'\', 0, \'catid=\' + document.id(\'catid\').value)"', null, '- ', 'filter'); + + $this->object = $this->_mainframe->getUserStateFromRequest('joom.mini.object', 'object', '', 'cmd'); + $this->search = $this->_mainframe->getUserStateFromRequest('joom.mini.search', 'search', '', 'string'); + } + + // Categories tab + if(isset($this->tabs['categories'])) + { + $this->categories_form = JForm::getInstance(_JOOM_OPTION.'.mini.categories', 'mini.categories'); + + $this->categories_form->setFieldAttribute('category_catid', 'onchange', str_replace('joom_', $this->prefix.'_', $this->categories_form->getFieldAttribute('category_catid', 'onchange'))); + $categories_fields = array('category_mode', 'category_limit', 'category_columns', 'category_ordering', 'category_linkedtext'); + foreach($categories_fields as $field) + { + $this->categories_form->setFieldAttribute($field, 'default', $this->params->get('default_'.$field)); + } + } + + // Upload tab + if(isset($this->tabs['upload'])) + { + $this->upload_form = JForm::getInstance(_JOOM_OPTION.'.mini.upload', 'mini.upload'); + + if($this->upload_catid) + { + $this->upload_form->setFieldAttribute('catid', 'default', $this->upload_catid); + } + else + { + $this->upload_form->setFieldAttribute('ajaxupload', 'insert_options', true); + } + + $this->editFilename = $this->_mainframe->isSite() ? $this->_config->get('jg_useruseorigfilename') : $this->_config->get('jg_useorigfilename'); + $this->delete_original = $this->_mainframe->isSite() ? ($this->_config->get('jg_delete_original_user') == 2) : ($this->_config->get('jg_delete_original') == 2); + + JText::script('COM_JOOMGALLERY_MINI_TYPE'); + JText::script('COM_JOOMGALLERY_MINI_POSITION'); + JText::script('COM_JOOMGALLERY_MINI_ALTTEXT'); + JText::script('COM_JOOMGALLERY_COMMON_THUMBNAIL'); + JText::script('COM_JOOMGALLERY_MINI_DETAIL'); + JText::script('COM_JOOMGALLERY_MINI_ORIGINAL'); + JText::script('JNONE'); + JText::script('JGLOBAL_CENTER'); + JText::script('JGLOBAL_LEFT'); + JText::script('JGLOBAL_RIGHT'); + } + + // Create category tab + if(isset($this->tabs['createcategory'])) + { + $this->category_form = JForm::getInstance(_JOOM_OPTION.'.mini.category', 'mini.category'); + + JText::script('COM_JOOMGALLERY_MINI_PLEASE_ENTER_TEXT'); + } + + // The parameter object is necessary for the even if it + // doesn't contain any data (this simplifies things) + if(!isset($this->params)) + { + $this->params = new JRegistry(); + $this->params->loadString(''); + } + + // Set some default values before possibly modifying the view + $this->upload_categories = null; + $this->parent_categories = null; + $this->upload_enabled = true; + $this->createcat_enabled = true; + + // If we are in frontend modify the view by adding possibility to + // change the category select boxes according to the plugin settings + if(!$this->upload_catid && $this->_mainframe->isSite()) + { + $this->modifyView(); + } + + JText::script('JLIB_FORM_FIELD_INVALID'); + + // Build the sorted message list + $messages = $this->_mainframe->getMessageQueue(); + $this->messages = array(); + if(is_array($messages) && !empty($messages)) + { + foreach($messages as $msg) + { + if(isset($msg['type']) && isset($msg['message'])) + { + $this->messages[$msg['type']][] = $msg['message']; + } + } + } + + parent::display($tpl); + } + + /** + * Modifies the view by adding possibility to change the + * category select boxes according to the plugin settings + * + * @return void + * @since 3.0 + */ + protected function modifyView() + { + // Upload + // The default is that uploading is enabled and that the complete category select box of JForm is used + if($this->params->get('upload_enabled')) + { + // Check whether only a part of the categories shall be available + $catids = explode(',', $this->params->get('upload_catids')); + if($this->params->get('upload_catids') && count($catids)) + { + $categories = $this->getModel()->getUploadCategories($catids); + if(!count($categories)) + { + // If no category is left disable the upload + $this->upload_enabled = false; + } + else + { + // Otherwise set the new category select box + $this->upload_categories = JHtml::_('select.genericlist', $categories, 'catid', null, 'cid', 'path', null, 'upload_categories'); + } + } + } + + // Create Category + // The default is that category creation is enabled and that the complete category select box of JForm is used + if($this->params->get('create_category')) + { + // Check whether only a part of the categories shall be available + $catids = explode(',', $this->params->get('parent_catids')); + if($this->params->get('parent_catids') && count($catids)) + { + $categories = $this->getModel()->getParentCategories($catids); + if(!count($categories)) + { + // If no category is left disable the category creation + $this->createcat_enabled = false; + } + else + { + // Otherwise set the new category select box + $this->parent_categories = JHtml::_('select.genericlist', $categories, 'parent_id', null, 'cid', 'path', null, 'parent_categories'); + } + } + } + } +} diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/move/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/move/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/move/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/move/tmpl/default.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/move/tmpl/default.php new file mode 100644 index 00000000..851c417d --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/move/tmpl/default.php @@ -0,0 +1,55 @@ + +
    +
    +
    + +
    +
    + lists['cats']; ?> +
    +
    + + + + + + + + + + + + +items as $i => $item): ?> + + + + + + + +
    + +
    + + + +
    + + + imgtitle; ?> + + + catid); ?> +
    +
    + + +
    +
    + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/move/view.html.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/move/view.html.php new file mode 100644 index 00000000..561f6cfb --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/move/view.html.php @@ -0,0 +1,49 @@ +_mainframe->getUserStateFromRequest('joom.move.catid', 'catid', 0, 'int'); + $items = $this->get('Images'); + $lists = array(); + $lists['cats'] = JHTML::_('joomselect.categorylist', $catid, 'catid', 'class="inputbox" size="1" ', null, '- ', null, 'joom.upload'); + + $this->assignRef('items', $items); + $this->assignRef('lists', $lists); + + parent::display($tpl); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/upload/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/upload/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/upload/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/upload/tmpl/default.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/upload/tmpl/default.php new file mode 100644 index 00000000..76518aa2 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/upload/tmpl/default.php @@ -0,0 +1,103 @@ + +
    +sidebar)): ?> +
    + sidebar; ?> +
    +
    + +
    + +
    +
    +
    +
    + form->getLabel('arrscreenshot'); ?> +
    + form->getInput('arrscreenshot'); ?> +
    +
    +
    +
    +
    +
    + form->getLabel('catid'); ?> +
    + form->getInput('catid'); ?> +
    +
    + _config->get('jg_useorigfilename')): ?> +
    + form->getLabel('imgtitle'); ?> +
    + form->getInput('imgtitle'); ?> +
    +
    + _config->get('jg_useorigfilename') && $this->_config->get('jg_filenamenumber')): ?> +
    + form->getLabel('filecounter'); ?> +
    + form->getInput('filecounter'); ?> +
    +
    + +
    + form->getLabel('imgtext'); ?> +
    + form->getInput('imgtext'); ?> +
    +
    +
    + form->getLabel('imgauthor'); ?> +
    + form->getInput('imgauthor'); ?> +
    +
    +
    + form->getLabel('published'); ?> +
    + form->getInput('published'); ?> +
    +
    +
    + form->getLabel('access'); ?> +
    + form->getInput('access'); ?> +
    +
    + _config->get('jg_delete_original') == 2): ?> +
    + form->getLabel('original_delete'); ?> +
    + form->getInput('original_delete'); ?> +
    +
    + +
    + form->getLabel('create_special_gif'); ?> +
    + form->getInput('create_special_gif'); ?> +
    +
    +
    + form->getLabel('debug'); ?> +
    + form->getInput('debug'); ?> +
    +
    +
    +
    + +
    +
    +
    +
    + + + + +
    + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/upload/tmpl/index.html b/deployed/joomgallery/administrator/components/com_joomgallery/views/upload/tmpl/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/upload/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/administrator/components/com_joomgallery/views/upload/view.html.php b/deployed/joomgallery/administrator/components/com_joomgallery/views/upload/view.html.php new file mode 100644 index 00000000..ac89d9f1 --- /dev/null +++ b/deployed/joomgallery/administrator/components/com_joomgallery/views/upload/view.html.php @@ -0,0 +1,58 @@ +_doc->addScriptDeclaration(' var jg_filenamewithjs = '.($this->_config->get('jg_filenamewithjs') ? 'true' : 'false').';'); + $this->_doc->addScript($this->_ambit->getScript('upload.js')); + JText::script('COM_JOOMGALLERY_COMMON_ALERT_IMAGE_MUST_HAVE_TITLE'); + JText::script('COM_JOOMGALLERY_COMMON_ALERT_YOU_MUST_SELECT_CATEGORY'); + JText::script('COM_JOOMGALLERY_COMMON_ALERT_YOU_MUST_SELECT_ONE_IMAGE'); + JText::script('COM_JOOMGALLERY_COMMON_ALERT_WRONG_EXTENSION'); + JText::script('COM_JOOMGALLERY_COMMON_ALERT_WRONG_FILENAME'); + JText::script('COM_JOOMGALLERY_UPLOAD_ALERT_FILENAME_DOUBLE_ONE'); + JText::script('COM_JOOMGALLERY_UPLOAD_ALERT_FILENAME_DOUBLE_TWO'); + + JForm::addFormPath(JPATH_COMPONENT.'/models/forms'); + $this->form = JForm::getInstance(_JOOM_OPTION.'.upload', 'upload'); + $this->form->setFieldAttribute('access', 'default', (int) JFactory::getConfig()->get('access')); + + if($this->_config->get('jg_useorigfilename')) + { + $this->form->setFieldAttribute('imgtitle', 'required', 'false'); + } + + $this->sidebar = JHtmlSidebar::render(); + + parent::display($tpl); + } +} diff --git a/deployed/joomgallery/components/com_joomgallery/controller.php b/deployed/joomgallery/components/com_joomgallery/controller.php new file mode 100644 index 00000000..0df2c81f --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/controller.php @@ -0,0 +1,176 @@ +_ambit = JoomAmbit::getInstance(); + $this->_config = JoomConfig::getInstance(); + + /*$this->_mainframe = JFactory::getApplication('site'); + $this->_user = JFactory::getUser();*/ + } + + /** + * Parent display method for all views + * + * @param boolean $cachable If true, the view output will be cached + * @param array $urlparams An array of safe URL parameters and their variable types, for valid values see {@link JFilterInput::clean()}. + * @return void + * @since 1.5.5 + */ + public function display($cachable = false, $urlparams = false) + { + // Set a default view if none exists + if(!$view = JRequest::getCmd('view')) + { + JRequest::setVar('view', 'gallery'); + } + + // Increase hit counter in detail view if image view isn't used + if($view == 'detail' && $this->_config->get('jg_use_real_paths')) + { + $this->getModel('image')->hit(JRequest::getInt('id')); + } + + parent::display($cachable, $urlparams); + + // Possibly delete zips + if( $view == 'favourites' + && + $this->_config->get('jg_favourites') + && + ( $this->_config->get('jg_zipdownload') + || $this->_config->get('jg_usefavouritesforpubliczip') + ) + ) + { + $this->_db = JFactory::getDBO(); + $query = $this->_db->getQuery(true) + ->select('uid, uuserid, zipname') + ->from(_JOOM_TABLE_USERS) + ->where('zipname != '.$this->_db->q('')) + ->where('time != '.$this->_db->q('')) + ->where('time < NOW()-INTERVAL 60 SECOND'); + $this->_db->setQuery($query); + $ziprows = $this->_db->loadObjectList(); + if(count($ziprows)) + { + jimport('joomla.filesystem.file'); + foreach($ziprows as $row) + { + if(JFile::exists($row->zipname)) + { + JFile::delete($row->zipname); + } + if($row->uuserid != 0) + { + $query->clear() + ->update(_JOOM_TABLE_USERS) + ->set('zipname = '.$this->_db->q('')) + ->set('time = '.$this->_db->q('')) + ->where('uid = '.(int) $row->uid); + $this->_db->setQuery($query); + } + else + { + $query->clear() + ->delete(_JOOM_TABLE_USERS) + ->where('uuserid = 0') + ->where('zipname = '.$this->_db->q($row->zipname)); + $this->_db->setQuery($query); + } + $this->_db->query(); + } + } + } + } + + /** + * Redirects to the image view with the download parameter set to 1. + * The image will be offered as a downloadable file then. + * + * @return void + * @since 1.5.5 + */ + public function download() + { + // Check permissions + if( !$this->_config->get('jg_download') + || (!$this->_config->get('jg_download_unreg') && !JFactory::getUser()->get('id')) + ) + { + $this->setRedirect(JRoute::_('index.php?view=gallery', false), JText::_('COM_JOOMGALLERY_COMMON_MSG_NOT_ALLOWED_VIEW_IMAGE'), 'notice'); + + return; + } + + $type = $this->_config->get('jg_downloadfile') ? 'orig' : 'img'; + + $this->setRedirect(JRoute::_('index.php?view=image&format=raw&id='.JRequest::getInt('id').'&download=1&type='.$type, false)); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/controllers/ajaxupload.raw.php b/deployed/joomgallery/components/com_joomgallery/controllers/ajaxupload.raw.php new file mode 100644 index 00000000..fb6e8070 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/controllers/ajaxupload.raw.php @@ -0,0 +1,70 @@ + false); + + require_once JPATH_COMPONENT_ADMINISTRATOR.'/helpers/upload.php'; + + $uploader = new JoomUpload(); + + if($image = $uploader->upload(JRequest::getCmd('type', 'ajax'))) + { + $result['success'] = true; + if(is_object($image)) + { + $result['id'] = $image->id; + $result['imgtitle'] = $image->imgtitle; + $result['thumbnailUrl'] = JoomAmbit::getInstance()->getImg('thumb_url', $image); + } + } + else + { + if($error = $uploader->getError()) + { + $result['error'] = $error; + } + else + { + $result['error'] = JText::_('COM_JOOMGALLERY_UPLOAD_ERROR_FILE_NOT_UPLOADED');; + } + } + + if($debug_output = $uploader->getDebugOutput()) + { + $result['debug_output'] = $debug_output; + } + + $doc = JFactory::getDocument(); + $doc->setMimeEncoding('text/plain'); + + echo json_encode($result); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/controllers/categories.json.php b/deployed/joomgallery/components/com_joomgallery/controllers/categories.json.php new file mode 100644 index 00000000..8a2eb98d --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/controllers/categories.json.php @@ -0,0 +1,99 @@ +getModel('categories'); + + $action = JRequest::getCmd('action'); + $filter = JRequest::getInt('filter'); + $search = JRequest::getString('searchstring'); + $limitstart = JRequest::getInt('more'); + $current = JRequest::getInt('current'); + + echo new JJsonResponse($model->getAllowedCategories($action, $filter, $search, $limitstart, $current)); + } + + /** + * Method to save the submitted ordering values for records via AJAX. + * + * @return void + * @since 3.0 + */ + public function saveOrder() + { + require_once JPATH_ADMINISTRATOR.'/components/com_languages/helpers/jsonresponse.php'; + + JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + + // Get the arrays from the request + $pks = JRequest::getVar('cid', null, 'post', 'array'); + $order = JRequest::getVar('order', null, 'post', 'array'); + $originalOrder = explode(',', JRequest::getString('original_order_values')); + + // Make sure something has changed + if($order !== $originalOrder) + { + // Create and load the categories table object + $table = JTable::getInstance('joomgallerycategories', 'Table'); + + if($table->saveorder($pks, $order)) + { + echo new JJsonResponse(); + } + } + } + + /** + * Unlocks a password protected category + * + * @return void + * @since 3.1 + */ + public function unlock() + { + require_once JPATH_ADMINISTRATOR.'/components/com_languages/helpers/jsonresponse.php'; + + $input = JFactory::getApplication()->input; + $model = $this->getModel('category'); + + try + { + $model->unlock($input->getInt('catid'), $input->getString('password')); + + echo new JJsonResponse(); + } + catch(Exception $e) + { + echo new JJsonResponse($e); + } + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/controllers/category.php b/deployed/joomgallery/components/com_joomgallery/controllers/category.php new file mode 100644 index 00000000..9f62bbe3 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/controllers/category.php @@ -0,0 +1,149 @@ +getModel('editcategory'); + + // Get limitstart from request to set the correct limitstart (page) for redirect url + $slimitstart = ''; + if(JRequest::getVar('limitstart', null) != null) + { + $slimitstart = '&limitstart='.JRequest::getInt('limitstart', 0); + } + + // Set default redirect URL + $redirect = 'index.php?view=usercategories'.$slimitstart; + + // Check whether a redirect is requested + if($url = JRequest::getVar('redirect', '', '', 'base64')) + { + $url = base64_decode($url); + if(JURI::isInternal($url)) + { + $redirect = $url; + } + } + + if($id = $model->store()) + { + $msg = JText::_('COM_JOOMGALLERY_COMMON_MSG_CATEGORY_SAVED'); + $this->setRedirect(JRoute::_($redirect, false), $msg); + } + else + { + $msg = $model->getError(); + $this->setRedirect(JRoute::_($redirect, false), $msg, 'error'); + } + } + + /** + * Deletes a category + * + * @return void + * @since 1.5.5 + */ + public function delete() + { + $model = $this->getModel('editcategory'); + + // Get limitstart from request to set the correct limitstart (page) for redirect url + $slimitstart = ''; + if(JRequest::getVar('limitstart', null) != null) + { + $slimitstart = '&limitstart='.JRequest::getInt('limitstart', 0); + } + + try + { + $model->delete(); + + $msg = JText::_('COM_JOOMGALLERY_COMMON_MSG_SUCCESS_DELETING_CATEGORY'); + $this->setRedirect(JRoute::_('index.php?view=usercategories'.$slimitstart, false), $msg); + } + catch(RuntimeException $e) + { + $this->setRedirect(JRoute::_('index.php?view=usercategories'.$slimitstart, false), $e->getMessage(), 'error'); + } + } + + /** + * Publishes resp. unpublishes a category + * + * @return void + * @since 1.5.7 + */ + public function publish() + { + $model = $this->getModel('editcategory'); + + // Get limitstart from request to set the correct limitstart (page) for redirect url + $slimitstart = ''; + if(JRequest::getVar('limitstart', null) != null) + { + $slimitstart = '&limitstart='.JRequest::getInt('limitstart', 0); + } + + if($model->publish()) + { + $msg = JText::_('COM_JOOMGALLERY_COMMON_MSG_SUCCESS_CHANGE_PUBLISH_STATE'); + $this->setRedirect(JRoute::_('index.php?view=usercategories'.$slimitstart, false), $msg); + } + else + { + $msg = $model->getError(); + $this->setRedirect(JRoute::_('index.php?view=usercategories'.$slimitstart, false), $msg, 'error'); + } + } + + /** + * Unlocks a password protected category + * + * @return void + * @since 3.1 + */ + public function unlock() + { + $input = JFactory::getApplication()->input; + $model = $this->getModel('category'); + + $catid = $input->getInt('catid'); + + try + { + $model->unlock($catid, $input->getString('password')); + } + catch(Exception $e) + { + $this->setMessage($e->getMessage(), 'error'); + } + + $this->setRedirect(JRoute::_('index.php?view=category&catid='.$catid, false)); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/controllers/comments.php b/deployed/joomgallery/components/com_joomgallery/controllers/comments.php new file mode 100644 index 00000000..b92b6196 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/controllers/comments.php @@ -0,0 +1,70 @@ +getModel('comments'); + + if(!$return = $model->save()) + { + $this->setRedirect(JRoute::_('index.php?view=detail&id='.$model->getId(), false), $model->getError(), 'error'); + } + else + { + if($return == 1) + { + $this->setRedirect(JRoute::_('index.php?view=detail&id='.$model->getId(), false), JText::_('COM_JOOMGALLERY_DETAIL_MSG_COMMENT_SAVED')); + } + else + { + $this->setRedirect(JRoute::_('index.php?view=detail&id='.$model->getId(), false), JText::_('COM_JOOMGALLERY_DETAIL_MSG_COMMENT_SAVED_BUT_NEEDS_ARROVAL')); + } + } + } + + /** + * Deletes a specific comment + * + * @return void + * @since 1.5.5 + */ + public function remove() + { + $model = $this->getModel('comments'); + + if(!$model->remove()) + { + $this->setRedirect(JRoute::_('index.php?view=detail&id='.$model->getId(), false), $model->getError(), 'error'); + } + else + { + $this->setRedirect(JRoute::_('index.php?view=detail&id='.$model->getId(), false), JText::_('COM_JOOMGALLERY_DETAIL_MSG_COMMENT_DELETED')); + } + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/controllers/favourites.php b/deployed/joomgallery/components/com_joomgallery/controllers/favourites.php new file mode 100644 index 00000000..4bda704d --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/controllers/favourites.php @@ -0,0 +1,193 @@ +getModel('favourites'); + + // Determine correct redirect URL + if($catid = JRequest::getInt('catid')) + { + // Request was initiated from category view + $url = JRoute::_('index.php?view=category&catid='.$catid, false); + } + elseif(($toplist = JRequest::getVar('toplist')) !== null) + { + // Request was initiated from toplist view + if(empty($toplist)) + { + // Toplist view 'Most viewed' + $url = JRoute::_('index.php?view=toplist', false); + } + else + { + // Any other toplist view + $url = JRoute::_('index.php?view=toplist&type='.$toplist, false); + } + } + elseif(($sstring = JRequest::getVar('sstring')) !== null) + { + // Request was initiated from search view + $url = JRoute::_('index.php?view=search&sstring='.$sstring, false); + } + else + { + // Request was initiated from detail view or any other view + $url = JRoute::_('index.php?view=detail&id='.$model->getId(), false); + } + + // Add the image to the list of favourite images + if(!$model->addImage()) + { + $this->setRedirect($url, $model->getError(), 'error'); + } + else + { + // Message is set by the model + $this->setRedirect($url); + } + } + + /** + * Adds all images of a category (but none of the sub-categories) to the list of the favourites + * + * @return void + * @since 1.5.5 + */ + public function addImages() + { + $catid = JRequest::getInt('catid'); + $model = $this->getModel('favourites'); + + // Determine correct redirect URL + if(JRequest::getCmd('return') == 'gallery') + { + // Request was initiated from gallery view + $url = JRoute::_('index.php?view=gallery', false); + } + else + { + if($return = JRequest::getInt('return')) + { + // Request was initiated from parent category view + $url = JRoute::_('index.php?view=category&catid='.(int) $return, false); + } + else + { + // Request was initiated from category view + $url = JRoute::_('index.php?view=category&catid='.$catid, false); + } + } + + // Add the image to the list of favourite images + if(!$model->addImages($catid)) + { + $this->setRedirect($url, $model->getError(), 'error'); + } + else + { + $this->setRedirect($url, $model->output('SUCCESSFULLY_ADDED_MORE')); + } + } + + /** + * Removes an image from the list of the favourites + * + * @return void + * @since 1.5.5 + */ + public function removeImage() + { + $model = $this->getModel('favourites'); + + if(!$model->removeImage()) + { + $this->setRedirect(JRoute::_('index.php?view=favourites', false), $model->getError(), 'error'); + } + else + { + $this->setRedirect(JRoute::_('index.php?view=favourites', false), $model->output('SUCCESSFULLY_REMOVED')); + } + } + + /** + * Clears the list of the favourites + * + * @return void + * @since 1.5.5 + */ + public function removeAll() + { + $model = $this->getModel('favourites'); + + if(!$model->removeAll()) + { + $this->setRedirect(JRoute::_('index.php?view=favourites', false), $model->getError(), 'error'); + } + else + { + $this->setRedirect(JRoute::_('index.php?view=favourites', false), $model->output('ALL_REMOVED')); + } + } + + /** + * Switches the layout of the favourites view + * + * @return void + * @since 1.5.5 + */ + public function switchLayout() + { + $model = $this->getModel('favourites'); + + $model->switchLayout(); + + $this->setRedirect(JRoute::_('index.php?view=favourites', false)); + } + + /** + * Creates a zip archive of the favourites + * + * @return void + * @since 1.5.5 + */ + public function createZip() + { + $model = $this->getModel('favourites'); + + if(!$model->createZip()) + { + $this->setRedirect(JRoute::_('index.php?view=favourites', false), JText::sprintf('COM_JOOMGALLERY_ERROR_CREATING_ZIP', $model->getError()), 'error'); + } + else + { + $this->setRedirect(JRoute::_('index.php?view=downloadzip', false)); + } + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/controllers/image.php b/deployed/joomgallery/components/com_joomgallery/controllers/image.php new file mode 100644 index 00000000..8c9a2c64 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/controllers/image.php @@ -0,0 +1,194 @@ +getModel('edit'); + + $array = JRequest::getVar('id', 0, '', 'array'); + + $model->setId((int)$array[0]); + + /*$data = JRequest::get('post'); + + //editing more than one image? + if(isset($data['cids'])) + { + //we need selected fields + if(!isset($data['change'])) + { + $this->setRedirect($this->_ambit->getRedirectUrl(), JText::_('Please check the boxes of fields you want to change'), 'notice'); + return; + } + + $cids_string = $data['cids']; + $cids = explode(',', $cids_string); + $change = $data['change']; + + //delete all unselected fields + foreach($data as $key => $value) + { + if(!in_array($key, $change)) + { + unset($data[$key]); + } + } + + //save each image + $return = array(); + foreach($cids as $cid) + { + $data['cid'] = $cid; + $return[] = $model->store($data); + } + + if(!in_array(false, $return)) + { + $this->setRedirect($this->_ambit->getRedirectUrl(), JText::sprintf('Successfully saved %d images.', count($return))); + } + else + { + $this->setRedirect($this->_ambit->getRedirectUrl(), JText::sprintf('Error saving images.'), 'error'); + } + return; + }*/ + + // Get limitstart from request to set the correct limitstart (page) for redirect url + $slimitstart = ''; + if(JRequest::getVar('limitstart', null) != null) + { + $slimitstart = '&limitstart='.JRequest::getInt('limitstart', 0); + } + + // Set standard redirect URL + $redirect = 'index.php?view=userpanel'.$slimitstart; + // Is there any redirect requested? + $url = JRequest::getVar('redirect', null, 'default', 'base64'); + if($url !== null) + { + $url = base64_decode($url); + if(JURI::isInternal($url)) + { + $redirect = $url; + } + } + + // Editing only one image + if($id = $model->store()) + { + $msg = JText::_('COM_JOOMGALLERY_COMMON_MSG_IMAGE_SAVED'); + $this->setRedirect(JRoute::_($redirect, false), $msg); + } + else + { + $msg = $model->getError(); + $this->setRedirect(JRoute::_($redirect, false), $msg, 'error'); + } + } + + /** + * Deletes an image + * + * @return void + * @since 1.5.5 + */ + public function delete() + { + $model = $this->getModel('edit'); + + $array = JRequest::getVar('id', 0, '', 'array'); + + $model->setId((int)$array[0]); + + // Get limitstart from request to set the correct limitstart (page) for redirect url + $slimitstart = ''; + if(JRequest::getVar('limitstart', null) != null) + { + $slimitstart = '&limitstart='.JRequest::getInt('limitstart', 0); + } + + // Set standard redirect URL + $redirect = 'index.php?view=userpanel'.$slimitstart; + // Is there any redirect requested? + $url = JRequest::getVar('redirect', null, 'default', 'base64'); + if($url !== null) + { + $url = base64_decode($url); + if(JURI::isInternal($url)) + { + $redirect = $url; + } + } + + try + { + $model->delete(); + + $msg = JText::_('COM_JOOMGALLERY_COMMON_MSG_IMAGE_AND_COMMENTS_DELETED'); + $this->setRedirect(JRoute::_($redirect, false), $msg); + } + catch(RuntimeException $e) + { + $this->setRedirect(JRoute::_($redirect, false), $e->getMessage(), 'error'); + } + } + + /** + * Publishes resp. unpublishes an image + * + * @return void + * @since 1.5.7 + */ + public function publish() + { + $model = $this->getModel('edit'); + + $array = JRequest::getVar('id', 0, '', 'array'); + + $model->setId((int)$array[0]); + + // Get limitstart from request to set the correct limitstart (page) for redirect url + $slimitstart = ''; + if(JRequest::getVar('limitstart', null) != null) + { + $slimitstart = '&limitstart='.JRequest::getInt('limitstart', 0); + } + + if($model->publish()) + { + $msg = JText::_('COM_JOOMGALLERY_COMMON_MSG_SUCCESS_CHANGE_PUBLISH_STATE'); + $this->setRedirect(JRoute::_('index.php?view=userpanel'.$slimitstart, false), $msg); + } + else + { + $msg = $model->getError(); + $this->setRedirect(JRoute::_('index.php?view=userpanel'.$slimitstart, false), $msg, 'error'); + } + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/controllers/images.json.php b/deployed/joomgallery/components/com_joomgallery/controllers/images.json.php new file mode 100644 index 00000000..1d3081f6 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/controllers/images.json.php @@ -0,0 +1,88 @@ +authorise('core.edit.state', _JOOM_OPTION.'.image.'.$cid[$i])) + { + continue; + } + + $row->load((int)$cid[$i]); + if($row->ordering != $order[$i]) + { + $row->ordering = $order[$i]; + if(!$row->store()) + { + break; + } + + // Remember the categories for reordering + $condition = 'catid = '.(int) $row->catid; + $found = false; + foreach($conditions as $cond) + { + if($cond == $condition) + { + $found = true; + break; + } + } + + if(!$found) + { + $conditions[] = $condition; + } + } + } + + // Execute reorder for each category + foreach($conditions as $cond) + { + $row->reorder($cond); + } + + echo new JJsonResponse(); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/controllers/index.html b/deployed/joomgallery/components/com_joomgallery/controllers/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/controllers/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/controllers/nametags.php b/deployed/joomgallery/components/com_joomgallery/controllers/nametags.php new file mode 100644 index 00000000..c557e018 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/controllers/nametags.php @@ -0,0 +1,63 @@ +getModel('nametags'); + + if(!$model->save()) + { + $this->setRedirect(JRoute::_('index.php?view=detail&id='.$model->getId(), false), $model->getError(), 'error'); + } + else + { + $this->setRedirect(JRoute::_('index.php?view=detail&id='.$model->getId(), false), JText::_('COM_JOOMGALLERY_DETAIL_NAMETAGS_MSG_SAVED')); + } + } + + /** + * Deletes a specific name tag + * + * @return void + * @since 2.1 + */ + public function remove() + { + $model = $this->getModel('nametags'); + + if(!$model->remove()) + { + $this->setRedirect(JRoute::_('index.php?view=detail&id='.$model->getId(), false), $model->getError(), 'error'); + } + else + { + $this->setRedirect(JRoute::_('index.php?view=detail&id='.$model->getId(), false), JText::_('COM_JOOMGALLERY_DETAIL_NAMETAGS_MSG_DELETED')); + } + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/controllers/report.php b/deployed/joomgallery/components/com_joomgallery/controllers/report.php new file mode 100644 index 00000000..1634e805 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/controllers/report.php @@ -0,0 +1,81 @@ +getModel('report'); + + // Determine correct redirect URL + $id = JRequest::getInt('id'); + $catid = JRequest::getInt('catid'); + $toplist = JRequest::getVar('toplist'); + $sstring = JRequest::getVar('sstring'); + + $redirect_url = 'index.php?view=detail&id='.$id; + if($catid) + { + // Request was initiated by category view + $redirect_url = 'index.php?view=category&catid='.$catid; + $query_append = 'catid='.$catid; + } + elseif($toplist !== null) + { + // Request was initiated from toplist view + if(empty($toplist)) + { + // Toplist view 'Most viewed' + $redirect_url = 'index.php?view=toplist'; + $query_append = 'toplist=mostviewed'; + } + else + { + // Any other toplist view + $redirect_url = 'index.php?view=toplist&type='.$toplist; + $query_append = 'toplist='.$toplist; + } + } + elseif($sstring !== null) + { + // Request was initiated from search view + $redirect_url = 'index.php?view=search&sstring='.$sstring; + $query_append = 'sstring='.$sstring; + } + + if(!$model->send($redirect_url)) + { + $this->setRedirect(JRoute::_('index.php?view=report&tmpl=component&id='.$id.$query_append, false), $model->getError(), 'error'); + } + else + { + $this->setRedirect(JRoute::_('index.php?view=report&tmpl=component&id='.$id.$query_append, false), JText::_('COM_JOOMGALLERY_COMMON_REPORT_SENT')); + } + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/controllers/send2friend.php b/deployed/joomgallery/components/com_joomgallery/controllers/send2friend.php new file mode 100644 index 00000000..a60232f7 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/controllers/send2friend.php @@ -0,0 +1,43 @@ +getModel('send2friend'); + + if(!$model->send()) + { + $this->setRedirect(JRoute::_('index.php?view=detail&id='.JRequest::getInt('id'), false), $model->getError(), 'error'); + } + else + { + $this->setRedirect(JRoute::_('index.php?view=detail&id='.JRequest::getInt('id'), false), JText::_('COM_JOOMGALLERY_DETAIL_SENDTOFRIEND_MSG_MAIL_SENT')); + } + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/controllers/upload.php b/deployed/joomgallery/components/com_joomgallery/controllers/upload.php new file mode 100644 index 00000000..831ec19b --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/controllers/upload.php @@ -0,0 +1,115 @@ +_mainframe = JFactory::getApplication(); + $type = $this->_mainframe->getUserStateFromRequest('joom.upload.type', 'type', 'single', 'post', 'cmd'); + + // If the applet in JAVA upload checks for the serverProtocol, + // it issues a HEAD request + // Simply return an empty doc to send a HTTP 200 + if($type == 'java' && $_SERVER['REQUEST_METHOD'] == 'HEAD') + { + jexit(); + } + + require_once JPATH_COMPONENT_ADMINISTRATOR.'/helpers/upload.php'; + $uploader = new JoomUpload(); + if($uploader->upload($type)) + { + $msg = JText::_('COM_JOOMGALLERY_UPLOAD_MSG_SUCCESSFULL'); + + // Set redirect if we are asked for that + if($redirect = JRequest::getVar('redirect', '', '', 'base64')) + { + $url = base64_decode($redirect); + if(JURI::isInternal($url)) + { + $this->setRedirect(JRoute::_($url, false), $msg); + + return; + } + } + + // Set a redirect according to the correspondent setting in configuration manager + $model = $this->getModel('upload'); + $url = $model->getRedirectUrlAfterUpload($type); + if(!empty($url)) + { + $this->setRedirect($url, $msg); + } + } + else + { + if($error = $uploader->getError()) + { + $this->setRedirect(JRoute::_('index.php?view=upload&tab='.$type, false), $error, 'error'); + } + } + } + + /** + * Handles results of the java upload + * + * @return void + * @since 1.5.7 + */ + public function concludejavaupload() + { + $this->_mainframe = JFactory::getApplication(); + $this->_config = JoomConfig::getInstance(); + + // Send a message if setted in configuration manager + if($this->_config->get('jg_msg_upload_type') != 0) + { + require_once(JPATH_COMPONENT.'/helpers/messenger.php'); + $this->_user = & JFactory::getUser(); + $counter = $this->_mainframe->getUserState('joom.upload.java.counter', 0); + $messenger = new JoomMessenger(); + $message = array( + 'from' => $this->_user->get('id'), + 'subject' => JText::_('COM_JOOMGALLERY_MESSAGE_NEW_IMAGES_SUBMITTED_SUBJECT'), + 'body' => JText::sprintf('COM_JOOMGALLERY_MESSAGE_NEW_IMAGES_SUBMITTED_BODY', $this->_config->get('jg_realname') ? $this->_user->get('name') : $this->_user->get('username'), $counter), + 'mode' => 'upload' + ); + $messenger->send($message); + } + $this->_mainframe->setUserState('joom.upload.java.counter', 0); + $msg = JText::_('COM_JOOMGALLERY_UPLOAD_MSG_SUCCESSFULL'); + + // Set a redirect according to the correspondent setting in configuration manager + $model = $this->getModel('upload'); + $url = $model->getRedirectUrlAfterUpload('java', 'java'); + if(!empty($url)) + { + $this->setRedirect($url, $msg); + } + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/controllers/userpanel.json.php b/deployed/joomgallery/components/com_joomgallery/controllers/userpanel.json.php new file mode 100644 index 00000000..f4fc8b85 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/controllers/userpanel.json.php @@ -0,0 +1,57 @@ +input->get('images', null, 'array'); + if(!$data || !is_array($data) || !count($data)) + { + throw new RuntimeException(JText::_('COM_JOOMGALLERY_COMMON_NO_IMAGE_SPECIFIED')); + } + + $model = $this->getModel('edit'); + + foreach($data as $id => $imageData) + { + $model->quickEdit($id, $imageData); + } + + echo new JResponseJson(); + } + catch(Exception $e) + { + echo new JResponseJson($e); + } + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/controllers/vote.json.php b/deployed/joomgallery/components/com_joomgallery/controllers/vote.json.php new file mode 100644 index 00000000..056f1438 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/controllers/vote.json.php @@ -0,0 +1,71 @@ +getModel('vote'); + + if(!$model->vote()) + { + echo new JJsonResponse(new Exception($model->getError())); + } + else + { + // HTML for updating the rating + JHtml::addIncludePath(JPATH_COMPONENT_ADMINISTRATOR.'/helpers/html'); + $response['rating'] = JHtml::_('joomgallery.rating', $model->getRating(), true, 'jg_starrating_detail', 'hasHintAjaxVote'); + + // Set CSS tooltip class in case of star rating + $response['tooltipclass'] = ''; + if($this->_config->get('jg_ratingdisplaytype') == 1) + { + if($this->_config->get('jg_tooltips') == 2) + { + $response['tooltipclass'] = 'jg-tooltip-wrap'; + } + else + { + if($this->_config->get('jg_tooltips') == 1) + { + $response['tooltipclass'] = 'default'; + } + } + } + + echo new JJsonResponse($response, JText::_('COM_JOOMGALLERY_DETAIL_RATINGS_MSG_YOUR_VOTE_COUNTED')); + } + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/controllers/vote.php b/deployed/joomgallery/components/com_joomgallery/controllers/vote.php new file mode 100644 index 00000000..19f5896b --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/controllers/vote.php @@ -0,0 +1,45 @@ +getModel('vote'); + + if(!$model->vote()) + { + $this->setRedirect(JRoute::_('index.php?view=detail&id='.$model->getId(), false), $model->getError(), 'error'); + } + else + { + $this->setRedirect(JRoute::_('index.php?view=detail&id='.$model->getId(), false), JText::_('COM_JOOMGALLERY_DETAIL_RATINGS_MSG_YOUR_VOTE_COUNTED')); + } + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/helpers/ambit.php b/deployed/joomgallery/components/com_joomgallery/helpers/ambit.php new file mode 100644 index 00000000..62b709a0 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/helpers/ambit.php @@ -0,0 +1,603 @@ +_config = $config; + + // Fill all variables + $this->icon_url = JURI::root().'media/joomgallery/images/'; + $this->css_url = JURI::root().'media/joomgallery/css/'; + $this->js_url = JURI::root().'media/joomgallery/js/'; + + $this->_external['thumb'] = false; + $this->thumb_url = JURI::root().$config->get('jg_paththumbs'); + $this->thumb_path = JPath::clean(JPATH_ROOT.'/'.$config->get('jg_paththumbs')); + + jimport('joomla.filesystem.folder'); + if(!JFolder::exists($this->thumb_path)) + { + $this->_external['thumb'] = true; + $this->thumb_url = ''; + $this->thumb_path = JPath::clean($config->get('jg_paththumbs')); + } + + $this->_external['img'] = false; + $this->img_url = JURI::root().$config->get('jg_pathimages'); + $this->img_path = JPath::clean(JPATH_ROOT.'/'.$config->get('jg_pathimages')); + if(!JFolder::exists($this->img_path)) + { + $this->_external['img'] = true; + $this->img_url = ''; + $this->img_path = JPath::clean($config->get('jg_pathimages')); + } + + $this->_external['orig'] = false; + $this->orig_url = JURI::root().$config->get('jg_pathoriginalimages'); + $this->orig_path = JPath::clean(JPATH_ROOT.'/'.$config->get('jg_pathoriginalimages')); + if(!JFolder::exists($this->orig_path)) + { + $this->_external['orig'] = true; + $this->orig_url = ''; + $this->orig_path = JPath::clean($config->get('jg_pathoriginalimages')); + } + + $this->temp_path = JPath::clean(JPATH_ROOT.'/'.$config->get('jg_pathtemp')); + if(!JFolder::exists($this->temp_path)) + { + $this->temp_path = JPath::clean($config->get('jg_pathtemp')); + } + $this->ftp_path = JPath::clean(JPATH_ROOT.'/'.$config->get('jg_pathftpupload')); + if(!JFolder::exists($this->ftp_path)) + { + $this->ftp_path = JPath::clean($config->get('jg_pathftpupload')); + } + $this->wtm_path = JPath::clean(JPATH_ROOT.'/'.$config->get('jg_wmpath')); + if(!JFolder::exists($this->wtm_path)) + { + $this->wtm_path = JPath::clean($config->get('jg_wmpath')); + } + } + + /** + * Returns a reference to the global Ambit object, only creating it if it + * doesn't already exist. + * + * This method must be invoked as: + *
      $ambit = JoomAmbit::getInstance();
    + * + * @return JoomAmbit The Ambit object. + * @since 1.5.5 + */ + public static function getInstance() + { + static $instance; + + if(!isset($instance)) + { + $instance = new JoomAmbit(); + } + + return $instance; + } + + /** + * Returns the URL to an icon + * + * @param string $icon The filename of the icon + * @return string The URL to the icon + * @since 1.5.5 + */ + public function getIcon($icon) + { + return $this->get('icon_url').$icon; + } + + /** + * Returns the URL to a style sheet + * + * @param string $stylesheet The filename of the style sheet + * @return string The URL to the style sheet + * @since 1.5.5 + */ + public function getStyleSheet($stylesheet) + { + return $this->get('css_url').$stylesheet; + } + + /** + * Returns the URL to a script file + * + * @param string $script The filename of the script file + * @return string The URL to the script file + * @since 1.5.5 + */ + public function getScript($script) + { + return $this->get('js_url').$script; + } + + /** + * Returns the URL or the path to an image + * + * @param string $type The type of the URL or path + * @param string/object/int $img Filename, database object or ID of the image + * @param int $catid The ID of the category in which the image is stored + * @param boolean $route True, if URLs should be parsed by the router + * @param int $cropwidth Width of cropped image if required + * @param int $cropheight Height of cropped image if required + * @param int $croppos Offset position of cropping window + * @return string The URL or the path to the image + * @since 1.5.5 + */ + public function getImg($type, $img, $id = null, $catid = 0, $route = true, $cropwidth = null, $cropheight = null, $croppos = null) + { + $types = array('thumb_path', 'thumb_url', 'img_path', 'img_url', 'orig_path', 'orig_url'); + if(!in_array($type, $types)) + { + JError::raiseError(500, JText::sprintf('Wrong image type: %s', $type)); + } + + if(!is_object($img)) + { + if(is_numeric($img)) + { + $img = $this->getImgObject($img); + } + else + { + if(!is_null($id)) + { + $img = $this->getImgObject($id); + } + } + } + + if(is_object($img)) + { + $id = $img->id; + $catid = $img->catid; + if($type == 'thumb_path' || $type == 'thumb_url') + { + $img = $img->imgthumbname; + } + else + { + $img = $img->imgfilename; + } + } + + // Check whether the image shall be output through the PHP script or with its real path + if( strpos($type, 'url') + && + ( $this->_external[str_replace('_url','', $type)] + || ($this->_config->get('jg_watermark') && strpos($type, 'thumb') === false) + || (strpos($type, 'img') !== false && !$this->_config->get('jg_use_real_paths')) + || (strpos($type, 'orig') !== false && !$this->_config->get('jg_use_real_paths')) + || !is_null($cropwidth) + ) + ) + { + $type = str_replace('_url','', $type); + $url = 'index.php?view=image&format=raw&type='.$type.'&id='.$id; + if(!is_null($cropwidth)) + { + $url .= '&width='.$cropwidth.'&height='.$cropheight.'&pos='.$croppos; + } + + if($route) + { + return JRoute::_($url); + } + + return $url; + } + + $catpath = JoomHelper::getCatPath($catid); + + // Create the complete path + $img = $this->$type . $catpath . $img; + + if(strpos($type, 'path')) + { + $img = JPath::clean($img); + } + + return $img; + } + + /** + * Returns the database row of a specific image + * + * @param int $id The ID of the image to load + * @return object The database row of the image + * @since 1.5.5 + */ + public function getImgObject($id) + { + static $images = array(); + static $row; + + if(!isset($images[$id])) + { + if(!isset($row)) + { + $row = JTable::getInstance('joomgalleryimages', 'Table'); + } + + if(!$row->load($id)) + { + JError::raiseError(500, JText::sprintf('Image with ID %d not found', $id)); + } + + $properties = $row->getProperties(); + $images[$id] = new stdClass(); + foreach($properties as $key => $value) + { + $images[$id]->$key = $value; + } + } + + return $images[$id]; + } + + /** + * Returns an Itemid of JoomGallery. + * + * At first, check if an Itemid was set in the configuration manager. + * If yes, use this one. If not, we use the Itemid of a menu item associated + * with the gallery. + * To prevent malformed URLs e.g. for SEF, an empty string is returned if no valid + * Itemid can be found in the database. + * + * @param boolean True, if a string like '&Itemid=X' should be constructed. + * @return int/string An Itemid of the gallery. + * @since 1.0.0 + */ + public function getItemid($string = true) + { + if(!isset($this->_Itemid) || is_null($this->_Itemid)) + { + $Itemid = intval($this->_config->get('jg_itemid')); + + if($Itemid) + { + $this->_Itemid = $Itemid; + } + else + { + $user = JFactory::getUser(); + $db = JFactory::getDBO(); + $lang = JFactory::getLanguage(); + + $query = $db->getQuery(true) + ->select('id') + ->from('#__menu') + ->where("link LIKE '%"._JOOM_OPTION."%view=gallery%'") + ->where('access IN ('.implode(',', $user->getAuthorisedViewLevels()).')') + ->where('published = 1') + ->where('client_id = 0') + ->where('(language = '.$db->q($lang->getTag()).' OR language = '.$db->q('').' OR language = '.$db->q('*').')') + ->order('id DESC'); + + $db->setQuery($query); + $Itemid = $db->loadResult(); + + if(!$Itemid) + { + $query->clear('where') + ->where("link LIKE '%"._JOOM_OPTION."%'") + ->where('access IN ('.implode(',', $user->getAuthorisedViewLevels()).')') + ->where('published = 1') + ->where('client_id = 0') + ->where('(language = '.$db->q($lang->getTag()).' OR language = '.$db->q('').' OR language = '.$db->q('*').')'); + + $db->setQuery($query); + $Itemid = $db->loadResult(); + } + + if($Itemid = intval($Itemid)) + { + $this->_Itemid = $Itemid; + } + else + { + $this->_Itemid = ''; + } + } + } + + return ($string && $this->_Itemid) ? '&Itemid='.$this->_Itemid : $this->_Itemid; + } + + /** + * Returns the category structure of the gallery + * + * @param boolean True, if a structure with all categories should be constructed. + * @return array An array of categories/sub-categories + * @since 1.5.5 + */ + public function getCategoryStructure($all = false) + { + // Check if already read from database + if( (is_null($this->_categorystructure) && !$all) + || (is_null($this->_allcategorystructure) && $all) + ) + { + // Creation of array + $database = JFactory::getDbo(); + $user = JFactory::getUser(); + + // Read all categories from database + $query = $database->getQuery(true) + ->select('c.cid, c.parent_id, c.name, c.access, c.published, c.hidden, c.owner') + ->from(_JOOM_TABLE_CATEGORIES.' AS c') + ->where('lft > 0') + ->order('c.lft'); + if(!$all) + { + $query->where('c.published = 1') + ->where('c.access IN ('.implode(',', $user->getAuthorisedViewLevels()).')') + ->where('(c.password = '.$database->q('').' OR c.cid IN ('.implode(',', JFactory::getApplication()->getUserState('joom.unlockedCategories', array(0))).'))'); + } + else + { + // In complete category structure we want to know the protected categories for creating the category tree view + $query->select('(CASE WHEN c.password != '.$database->quote('').' AND c.cid NOT IN ('.implode(',', JFactory::getApplication()->getUserState('joom.unlockedCategories', array(0))).') THEN 1 ELSE 0 END) AS protected'); + } + + $database->setQuery($query); + $categories = $database->loadObjectList('cid'); + + // Get picture count and hits count + $query->clear() + ->select('catid, COUNT(id) as piccount, SUM(hits) as hitcount') + ->from(_JOOM_TABLE_IMAGES) + ->group('catid'); + if(!$all) + { + $query->where('approved = 1') + ->where('published = 1') + ->where('hidden = 0') + ->where('access IN ('.implode(',', $user->getAuthorisedViewLevels()).')'); + } + + $database->setQuery($query); + $catcounts = $database->loadObjectList('catid'); + + // Merge the arrays + foreach($categories as $key => $category) + { + if($category->parent_id != 1 && !isset($categories[$category->parent_id])) + { + unset($categories[$key]); + continue; + } + + // Cast to int where needful + $categories[$key]->cid = (int) $key; + $categories[$key]->parent_id = (int) $categories[$key]->parent_id; + + if(isset($catcounts[$key])) + { + $categories[$key]->piccount = (int) $catcounts[$key]->piccount; + $categories[$key]->hitcount = (int) $catcounts[$key]->hitcount; + } + else + { + $categories[$key]->piccount = 0; + $categories[$key]->hitcount = 0; + } + } + + // Avoid empty category structure for preventing SQL errors + if(empty($categories)) + { + $categories[0] = new stdClass(); + $categories[0]->cid = 0; + $categories[0]->name = 'ROOT'; + $categories[0]->parent_id = 1; + $categories[0]->owner = 0; + $categories[0]->access = 0; + $categories[0]->hidden = 0; + $categories[0]->piccount = 0; + $categories[0]->hitcount = 0; + } + + if($all) + { + $this->_allcategorystructure = $categories; + } + else + { + $this->_categorystructure = $categories; + } + } + if(!$all) + { + return $this->_categorystructure; + } + else + { + return $this->_allcategorystructure; + } + } + + /** + * Returns the category structure of the gallery from cache + * + * @return array An array of categories/sub-categories + * @since 1.5.5 + */ +// public function getCategoryStructureFromCache() +// { +// jimport('joomla.cache.cache'); +// jimport('joomla.cache.callback'); +// +// // TODO Parameter for set caching and caching lifetime +// if(is_null($this->_categorystructure)) +// { +// $cache = JCache::getInstance('callback', array +// ( +// 'defaultgroup' => 'joomgallery', +// 'cachebase' => JPATH_BASE . '/cache/', +// 'lifetime' => 60, +// 'language' => 'en-GB', +// 'storage' => 'file' +// ) +// ); +// +// // enabling caching +// $cache->setCaching(true); +// +// // Cache id must be unique to what you are caching +// $cache_id = md5('joomgallery_CategoryStructure'); +// +// $this->_categorystructure = $cache->get(array($this, 'getCategoryStructureFromDB') , array(), $cache_id); +// } +// +// return $this->_categorystructure; +// } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/helpers/helper.php b/deployed/joomgallery/components/com_joomgallery/helpers/helper.php new file mode 100644 index 00000000..5f24d234 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/helpers/helper.php @@ -0,0 +1,971 @@ +getCategoryStructure(true); + $allowedCategories = array(); + foreach($cats as $category) + { + $action2 = false; + if($action == 'joom.upload') + { + $action2 = 'joom.upload.inown'; + } + if($action == 'core.create') + { + $action2 = 'joom.create.inown'; + } + if($action == 'core.edit') + { + $action2 = 'core.edit.own'; + } + + if( $user->authorise($action, _JOOM_OPTION.'.category.'.$category->cid) + || ( $action2 + && $category->owner + && $category->owner == $user->get('id') + && $user->authorise($action2, _JOOM_OPTION.'.category.'.$category->cid) + ) + ) + { + $allowedCategories[] = $category; + } + } + + return $allowedCategories; + } + + /** + * Fix text for output in JavaScript Code + * + * @param string $text The text to fix + * @return string The fixed text + * @since 1.0.0 + */ + public static function fixForJS($text) + { + $text = str_replace("\"", "\"", $text); + $text = str_replace("'", "\'", $text); + $text = preg_replace('/[\n\t\r]*/', '', $text); + + return $text; + } + + /** + * Wrap text + * + * @param string $text The text to wrap + * @param int $nr Number of chars to wrap + * @return string The wrapped text + * @since 1.0.0 + */ + public static function processText($text, $nr = 40) + { + $mytext = explode(' ', trim($text)); + $newtext = array(); + $config = JoomConfig::getInstance(); + + foreach($mytext as $k => $txt) + { + if(strlen($txt) > $nr) + { + // Do not wrap BBcode [url] and [email] + if( + !$config->get('jg_bbcodesupport') + || ( stripos($txt,'[url') === false && stripos($txt,'[/url]') === false + && stripos($txt,'[email') === false && stripos($txt,'[/email]') === false + ) + ) + { + $txt = wordwrap($txt, $nr, '- ', true); + } + } + + $newtext[] = $txt; + } + + return implode(' ', $newtext); + } + + /** + * Reads the category path from array + * If not set read database and add to array + * + * @param int $catid The ID of the category of which the catpath is requested + * @return string The catpath of the category + * @since 1.0.0 + */ + public static function getCatPath($catid) + { + static $catpath = array(); + + if(!isset($catpath[$catid])) + { + $database = JFactory::getDBO(); + $query = $database->getQuery(true) + ->select('catpath') + ->from(_JOOM_TABLE_CATEGORIES) + ->where('cid = '.$catid); + $database->setQuery($query); + + if(!$path = $database->loadResult()) + { + $catpath[$catid] = '/'; + } + else + { + $catpath[$catid] = $path.'/'; + } + } + + return $catpath[$catid]; + } + + /** + * Check the upload time of image and determine if it is within a setted span + * of time and so marked as NEW + * + * @param int $uptime Upload time in seconds + * @param int $daysnew Span of time in days + * @return string The HTML output of the new icon or empty string + * @since 1.0.0 + */ + public static function checkNew($uptime, $daysnew) + { + $isnew = ''; + + // Get the seconds from starting time of Unix Epoch (January 1 1970 00:00:00 GMT) + // to now in seconds + $thistime = time(); + // Calculate the seconds according to days setted for new + // See configuration manager + $timefornew = 86400 * $daysnew; + // If span of time since upload is lower than span of time setted in config + if(($thistime - strtotime($uptime)) < $timefornew) + { + // Show the 'new' image + $isnew = JHTML::_('joomgallery.icon', 'new.png', 'New'); + } + + return $isnew; + } + + /** + * Checks images of category and possibly sub-categories + * and calls checkNew() to decide if NEW + * + * @param string $catids_values IDs of categories ('x,y') + * @return string HTML output of the new icon or empty string + * @since 1.0.0 + */ + public static function checkNewCatg($cid) + { + $config = JoomConfig::getInstance(); + $db = JFactory::getDBO(); + $user = JFactory::getUser(); + $isnewcat = ''; + + // Get all sub-categories including the current category + $catids = JoomHelper::getAllSubCategories($cid, true); + + if(count($catids)) + { + // Implode array to a comma separated string if more than one element in array + $catid_values = implode(',', $catids); + // Search in db the categories in $catids_values + $query = $db->getQuery(true) + ->select('MAX(imgdate)') + ->from(_JOOM_TABLE_IMAGES.' AS a') + ->leftJoin(_JOOM_TABLE_CATEGORIES.' AS c ON c.cid = a.catid') + ->where('a.catid IN ('.$catid_values.')'); + $db->setQuery($query); + + $maxdate = $db->loadResult(); + if($db->getErrorNum()) + { + JError::raiseWarning(500, $db->getErrorMsg()); + } + + // If maxdate = NULL no image found + // Otherwise check the date to 'new' + if($maxdate) + { + $isnewcat = JoomHelper::checkNew($maxdate, $config->get('jg_catdaysnew')); + } + } + + // If no new found at all + // Return empty string + return $isnewcat; + } + + /** + * Construct page title + * + * @param string $text The structure of the page title to use + * @param string $catname The name of the category which is currently displayed + * or in which the currently displayed image is + * @param string $imgtitle The name of the image which is currently displayed + * @param string $page_title The page title + * @return string modified title + * @since 1.0.0 + */ + public static function createPagetitle($text, $catname = '', $imgtitle = '', $page_title = '') + { + preg_match_all('/(\[\!.*?\!\])/i', $text, $results); + define('COM_JOOMGALLERY_COMMON_CATEGORY', JText::_('COM_JOOMGALLERY_COMMON_CATEGORY')); + define('COM_JOOMGALLERY_COMMON_IMAGE', JText::_('COM_JOOMGALLERY_COMMON_IMAGE')); + for($i = 0; $igetCfg('sitename_pagetitles')) + { + if($app->getCfg('sitename_pagetitles') == 1) + { + $pagetitle = JText::sprintf('JPAGETITLE', $app->getCfg('sitename'), $pagetitle); + } + else + { + $pagetitle = JText::sprintf('JPAGETITLE', $pagetitle, $app->getCfg('sitename'), $pagetitle); + } + } + + return $pagetitle; + } + + /** + * Returns all categories and their sub-categories with published or no images + * + * @param int $cat Category ID + * @param boolean $rootcat True, if $cat shall also be returned as an + * element of the array + * @param boolean $noimgcats True if @return shall also include categories + * with no images + * @param boolean $all True if all categories shall be selected, defaults to false + * @param boolean $nohiddencats True, if hidden categories and it's subcategories should be + * filtered out, defaults to true + * @return array An array of found categories + * @since 1.5.5 + */ + public static function getAllSubCategories($cat, $rootcat = false, $noimgcats = false, $all = false, $nohiddencats = true) + { + // Initialise variables + $cat = (int) $cat; + $parentcats = array(); + $parentcats[$cat] = true; + $branchfound = false; + $allsubcats = array(); + + // Get category structure from ambit + $ambit = JoomAmbit::getInstance(); + $cats = $ambit->getCategoryStructure($all); + + $stopindex = count($cats); + + $keys = array_keys($cats); + $startindex = array_search($cat, $keys); + if($startindex === false) + { + return $allsubcats; + } + + // Find all cats which are subcategories of cat + $hidden = array(); + for($j = $startindex + 1; $j < $stopindex; $j++) + { + $i = $keys[$j]; + $parentcat = $cats[$i]->parent_id; + if(isset($parentcats[$parentcat])) + { + $parentcats[$i] = true; + $branchfound = true; + + // Don't include hidden sub-categories + if($nohiddencats) + { + if($cats[$i]->hidden) + { + $hidden[$i] = true; + } + else + { + if(isset($hidden[$cats[$i]->parent_id])) + { + $hidden[$i] = true; + } + } + } + + if(!isset($hidden[$i])) + { + if(!$noimgcats) + { + // Only categories with images + if($cats[$i]->piccount > 0) + { + // Subcategory with images in array + $allsubcats[] = $i; + } + } + else + { + $allsubcats[] = $i; + } + } + } + else + { + if($branchfound) + { + // Branch has been processed completely + break; + } + } + } + + // Add rootcat + if($rootcat) + { + if(!$noimgcats) + { + // Includes images + if($cats[$cat]->piccount > 0) + { + $allsubcats[] = $cat; + } + } + else + { + $allsubcats[] = $cat; + } + } + + return $allsubcats; + } + + /** + * Returns all parent categories of a specific category + * + * @param int $category The ID of the specific child category + * @param boolean $child True, if category itself shall also be returned, defaults to false + * @param boolean $all True if all categories shall be shown, defaults to false + * @return array An array of parent category objects with cid,name,parent_id + * @since 1.5.5 + */ + public static function getAllParentCategories($category, $child = false, $all = false) + { + // Get category structure from ambit + $ambit = JoomAmbit::getInstance(); + $cats = $ambit->getCategoryStructure($all); + $parents = array(); + + if($child) + { + $parents[$category] = new stdClass(); + $parents[$category]->cid = $cats[$category]->cid; + $parents[$category]->name = $cats[$category]->name; + $parents[$category]->parent_id = $cats[$category]->parent_id; + $parents[$category]->published = $cats[$category]->published; + } + + $parentcat = $cats[$category]->parent_id; + while($parentcat != 1) + { + $category = $parentcat; + $parents[$category] = new stdClass(); + $parents[$category]->cid = $cats[$category]->cid; + $parents[$category]->name = $cats[$category]->name; + $parents[$category]->parent_id = $cats[$category]->parent_id; + $parents[$category]->published = $cats[$category]->published; + $parentcat = $cats[$category]->parent_id; + } + + // Reverse the array to get the right order + $parents = array_reverse($parents, true); + + return $parents; + } + + /** + * Returns all available smileys in an array + * + * @return array An array with the smileys + * @since 1.5.0 + */ + public static function getSmileys() + { + $config = JoomConfig::getInstance(); + + $path = JoomAmbit::getInstance()->get('icon_url').'smilies/'.$config->jg_smiliescolor.'/'; + + $smileys = array(); + $smileys[':smile:'] = $path.'sm_smile.gif'; + $smileys[':cool:'] = $path.'sm_cool.gif'; + $smileys[':grin:'] = $path.'sm_biggrin.gif'; + $smileys[':wink:'] = $path.'sm_wink.gif'; + $smileys[':none:'] = $path.'sm_none.gif'; + $smileys[':mad:'] = $path.'sm_mad.gif'; + $smileys[':sad:'] = $path.'sm_sad.gif'; + $smileys[':dead:'] = $path.'sm_dead.gif'; + + if($config->get('jg_anismilie')) + { + $smileys[':yes:'] = $path.'sm_yes.gif'; + $smileys[':lol:'] = $path.'sm_laugh.gif'; + $smileys[':smilewinkgrin:'] = $path.'sm_smilewinkgrin.gif'; + $smileys[':razz:'] = $path.'sm_bigrazz.gif'; + $smileys[':roll:'] = $path.'sm_rolleyes.gif'; + $smileys[':eek:'] = $path.'sm_bigeek.gif'; + $smileys[':no:'] = $path.'sm_no.gif'; + $smileys[':cry:'] = $path.'sm_cry.gif'; + } + + $dispatcher = JDispatcher::getInstance(); + $dispatcher->trigger('onJoomGetSmileys', array(&$smileys)); + + return $smileys; + } + + /** + * At the moment just a wrapper function for JModuleHelper::getModules() + * + * @param string $pos The position name + * @return array An array of module objects + * @since 1.5.0 + */ + public static function getModules($pos) + { + $view = JRequest::getCmd('view'); + + $position = 'jg_'.$pos; + $modules = & JModuleHelper::getModules($position); + + $views = array( '' => 'gal', + 'gallery' => 'gal', + 'category' => 'cat', + 'detail' => 'dtl', + 'toplist' => 'tpl', + 'search' => 'sea', + 'favourites' => 'fav', + 'userpanel' => 'usp', + 'upload' => 'upl' + ); + if(isset($views[$view])) + { + $position = $position.'_'.$views[$view]; + $ind_mods = & JModuleHelper::getModules($position); + $modules = array_merge($modules, $ind_mods); + } + + $ind_mods = & JModuleHelper::getModules($position.'_'.$view); + $modules = array_merge($modules, $ind_mods); + + return $modules; + } + + /** + * Renders modules provided by getModules() + * + * @param string $pos The position name + * @return array An array of rendered modules + * @since 1.5.5 + */ + public static function getRenderedModules($pos) + { + static $renderer; + + $modules = JoomHelper::getModules($pos); + + if(count($modules)) + { + if(!isset($renderer)) + { + $document = JFactory::getDocument(); + $renderer = $document->loadRenderer('module'); + } + + $style = -2; + $params = array('style' => $style); + + foreach($modules as $key => $module) + { + $modules[$key]->rendered = $renderer->render($module, $params); + } + } + + return $modules; + } + + /** + * Sets all params for the output depending on the view and the config settings + * + * @param $params The parameter object + * @return void + * @since 1.5.5 + */ + public static function prepareParams(&$params) + { + $config = JoomConfig::getInstance(); + $user = JFactory::getUser(); + $view = JRequest::getCmd('view'); + $app = JFactory::getApplication('site'); + + // Page heading + $menus = $app->getMenu(); + $menu = $menus->getActive(); + if($menu) + { + $params->def('page_heading', $params->get('page_title', $menu->title)); + } + else + { + $params->def('page_heading', JText::_('COM_JOOMGALLERY_COMMON_GALLERY')); + if($config->get('jg_showgalleryhead')) + { + $params->set('show_page_heading', 1); + } + } + + // Pathway + if(!$params->get('disable_global_info') && ($view != 'gallery' || $config->get('jg_showgallerysubhead'))) + { + // Pathway in the header + if($config->get('jg_showpathway') == 1 || $config->get('jg_showpathway') == 3) + { + $params->set('show_header_pathway', 1); + } + // Pathway in the footer + if($config->get('jg_showpathway') >= 2) + { + $params->set('show_footer_pathway', 1); + } + } + + // Search in the header + if(!$params->get('disable_global_info') && ($config->get('jg_search') == 1 || $config->get('jg_search') == 3)) + { + $params->set('show_header_search', 1); + } + //Search in the footer + if(!$params->get('disable_global_info') && $config->get('jg_search') >= 2) + { + $params->set('show_footer_search', 1); + } + + // Backlink in the header + if(!$params->get('disable_global_info') && ($config->get('jg_showbacklink') == 1 || $config->get('jg_showbacklink') == 3)) + { + $params->set('show_header_backlink', 1); + } + // Backlink in the footer + if(!$params->get('disable_global_info') && $config->get('jg_showbacklink') >= 2) + { + $params->set('show_footer_backlink', 1); + } + + // All images + if(!$params->get('disable_global_info')) + { + // All Images in the header + if($config->get('jg_showallpics') == 1 || $config->get('jg_showallpics') == 3) + { + $params->set('show_header_allpics', 1); + } + // All Images in the footer + if($config->get('jg_showallpics') >= 2) + { + $params->set('show_footer_allpics', 1); + } + } + + // All hits + if(!$params->get('disable_global_info')) + { + // All Hits in the header + if($config->get('jg_showallhits') == 1 || $config->get('jg_showallhits') == 3) + { + $params->set('show_header_allhits', 1); + } + // All Hits in the footer + if($config->get('jg_showallhits') >= 2) + { + $params->set('show_footer_allhits', 1); + } + } + + // Link to userpanel in the header + if(!$params->get('disable_global_info') && $config->get('jg_userspace') == 1 && $config->get('jg_showuserpanel')) + { + if($user->get('id') || $config->get('jg_unregistered_permissions') || $config->get('jg_showuserpanel_unreg')) + { + if($user->get('id') || $config->get('jg_unregistered_permissions')) + { + $params->set('show_mygal', 1); + } + else + { + if($config->get('jg_showuserpanel_hint')) + { + $params->set('show_mygal_no_access', 1); + } + } + } + } + + // Link to favourites in the header + if(!$params->get('disable_global_info') && $config->get('jg_favourites')) + { + if($view != 'favourites') + { + if( $user->get('id') + || (($config->get('jg_usefavouritesforpubliczip') == 1) && !$user->get('id')) + ) + { + if( ($config->get('jg_usefavouritesforzip') == 1) + || (($config->get('jg_usefavouritesforpubliczip') == 1) && !$user->get('id')) + ) + { + $params->set('show_favourites', 1); + } + else + { + $tooltip_text = JText::_('COM_JOOMGALLERY_COMMON_FAVOURITES_DOWNLOAD_TIPTEXT', true); + if($config->get('jg_zipdownload') && $view != 'createzip') + { + $tooltip_text .= ' '.JText::_('COM_JOOMGALLERY_COMMON_DOWNLOADZIP_DOWNLOAD_ALLOWED_TIPTEXT', true); + } + $params->set('show_favourites', 2); + $params->set('favourites_tooltip_text', $tooltip_text); + } + } + else + { + if($config->get('jg_favouritesshownotauth') == 1) + { + if($config->get('jg_usefavouritesforzip') == 1) + { + $params->set('show_favourites', 3); + } + else + { + $params->set('show_favourites', 4); + } + } + } + } + else + { + if( $config->get('jg_zipdownload') + || (!$user->get('id') && $config->get('jg_usefavouritesforpubliczip')) + ) + { + $params->set('show_favourites', 5); + } + } + } + + // Toplist + if( ( $config->get('jg_whereshowtoplist') == 0 + || ($config->get('jg_whereshowtoplist') > 0 && $view == 'gallery') + || ($config->get('jg_whereshowtoplist') == 2 && $view == 'category') + ) + && + !$params->get('disable_global_info') + ) + { + // Toplist in the header + if( $config->get('jg_showtoplist') > 0 + && $config->get('jg_showtoplist') < 3 + ) + { + $params->set('show_header_toplist', 1); + } + // Toplist in the footer + if($config->get('jg_showtoplist') > 1) + { + $params->set('show_footer_toplist', 1); + } + } + + // RM/SM Legend in the footer + if($config->get('jg_showrestrictedhint') == 1 && ($view == 'gallery' || $view == 'category')) + { + $params->set('show_rmsm_legend', 1); + } + + // Separator in the footer + if($view == 'detail' || $view == 'favourites' || $view == 'search' || $view == 'toplist') + { + $params->set('show_footer_separator', 1); + } + + // Credits in the footer + if($config->get('jg_suppresscredits')) + { + $params->set('show_credits', 1); + } + } + + /** + * Counts images and hits in gallery or a category and their sub-categories + * + * @param int $cat Category ID or 0 to return images/hits of gallery + * @param boolean $rootcat True to count the images/hits also in category = $cid + * @return array 0 = Number of images in categories->subcategories.... + * 1 = Number of hits in categories->subcategories.... + * @since 1.5.7 + */ + public static function getNumberOfImgHits($cat = 0, $rootcat = true) + { + // Initialise variables + $cat = (int) $cat; + $imgHitsarr = array(); + $imgcount = 0; + $hitcount = 0; + + // Get category structure from ambit + $ambit = JoomAmbit::getInstance(); + $cats = $ambit->getCategoryStructure(); + + if($cat == 0) + { + // Count all images and hits in gallery + foreach($cats as $category) + { + $imgcount += $category->piccount; + $hitcount += $category->hitcount; + } + } + else + { + $branchfound = false; + $parentcats = array(); + $parentcats[$cat] = true; + + $keys = array_keys($cats); + $startindex = array_search($cat, $keys); + + $stopindex = count($cats); + + if($rootcat && isset($cats[$cat])) + { + $imgcount += $cats[$cat]->piccount; + $hitcount += $cats[$cat]->hitcount; + } + + // Count all images in branch + $hidden = array(); + for($j = $startindex + 1; $j < $stopindex; $j++) + { + $i = $keys[$j]; + $parentcat = $cats[$i]->parent_id; + if(isset($parentcats[$parentcat])) + { + $parentcat = $i; + $parentcats[$parentcat] = true; + + // Don't count images and hits of hidden categories + if($cats[$i]->hidden) + { + $hidden[$i] = true; + } + else + { + if(isset($hidden[$cats[$i]->parent_id])) + { + $hidden[$i] = true; + } + } + + if(!isset($hidden[$i])) + { + $hitcount += $cats[$i]->hitcount; + $imgcount += $cats[$i]->piccount; + } + + $branchfound = true; + } + else + { + if($branchfound) + { + // Branch has been processed completely + break; + } + } + } + + } + + $imgHitsarr[0] = number_format($imgcount, 0, JText::_('COM_JOOMGALLERY_COMMON_DECIMAL_SEPARATOR'), JText::_('COM_JOOMGALLERY_COMMON_THOUSANDS_SEPARATOR')); + $imgHitsarr[1] = number_format($hitcount, 0, JText::_('COM_JOOMGALLERY_COMMON_DECIMAL_SEPARATOR'), JText::_('COM_JOOMGALLERY_COMMON_THOUSANDS_SEPARATOR')); + + return $imgHitsarr; + } + + /** + * Returns the rating clause for an SQL - query dependent on the + * rating calculation method selected. + * + * @param string $tablealias The table alias to use + * @return string Rating clause + * @since 1.5.6 + */ + public static function getSQLRatingClause($tablealias = '') + { + $db = JFactory::getDBO(); + $config = JoomConfig::getInstance(); + static $avgimgvote = 0.0; + static $avgimgrating = 0.0; + static $avgdone = false; + + $maxvoting = $config->get('jg_maxvoting'); + $imgvotesum = 'imgvotesum'; + $imgvotes = 'imgvotes'; + if($tablealias != '') + { + $imgvotesum = $tablealias.'.'.$imgvotesum; + $imgvotes = $tablealias.'.'.$imgvotes; + } + + // Standard rating clause + $clause = 'ROUND(LEAST(IF(imgvotes > 0, '.$imgvotesum.'/'.$imgvotes.', 0.0), '.(float)$maxvoting.'), 2)'; + + // Advanced (weigthed) rating clause (Bayes) + if($config->get('jg_ratingcalctype') == 1) + { + if(!$avgdone) + { + // Needed values for weighted rating calculation + $query = $db->getQuery(true) + ->select('count(*) As imgcount') + ->select('SUM(imgvotes) As sumimgvotes') + ->select('SUM(imgvotesum/imgvotes) As sumimgratings') + ->from(_JOOM_TABLE_IMAGES) + ->where('imgvotes > 0'); + $db->setQuery($query); + + $row = $db->loadObject(); + if($row != null) + { + if($row->imgcount > 0) + { + $avgimgvote = round($row->sumimgvotes / $row->imgcount, 2 ); + $avgimgrating = round($row->sumimgratings / $row->imgcount, 2); + $avgdone = true; + } + } + } + if($avgdone) + { + $clause = 'ROUND(LEAST(IF(imgvotes > 0, (('.$avgimgvote.'*'.$avgimgrating.') + '.$imgvotesum.') / ('.$avgimgvote.' + '.$imgvotes.'), 0.0), '.(float)$maxvoting.'), 2)'; + } + } + + return $clause; + } + + /** + * Converts a given size with units e.g. read from php.ini to bytes. + * + * @param string $val Value with units (e.g. 8M) + * @return int Value in bytes + * @since 3.0 + */ + + public static function iniToBytes($val) + { + $val = trim($val); + + switch(strtolower(substr($val, -1))) + { + case 'm': + $val = (int)substr($val, 0, -1) * 1048576; + break; + case 'k': + $val = (int)substr($val, 0, -1) * 1024; + break; + case 'g': + $val = (int)substr($val, 0, -1) * 1073741824; + break; + case 'b': + switch(strtolower(substr($val, -2, 1))) + { + case 'm': + $val = (int)substr($val, 0, -2) * 1048576; + break; + case 'k': + $val = (int)substr($val, 0, -2) * 1024; + break; + case 'g': + $val = (int)substr($val, 0, -2) * 1073741824; + break; + default: + break; + } + break; + default: + break; + } + + return $val; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/helpers/index.html b/deployed/joomgallery/components/com_joomgallery/helpers/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/helpers/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/helpers/messenger.php b/deployed/joomgallery/components/com_joomgallery/helpers/messenger.php new file mode 100644 index 00000000..3750b927 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/helpers/messenger.php @@ -0,0 +1,572 @@ +realname = $config->get('jg_realname') ? true : false; + $this->globalfrom = $config->get('jg_msg_global_from') ? true : false; + + // Predefined message send modes + $this->addMode( array('name' => 'upload', + 'recipients' => explode(',', $config->get('jg_msg_upload_recipients')), + 'type' => $config->get('jg_msg_upload_type') + ) + ); + $this->addMode( array('name' => 'download', + 'recipients' => explode(',', $config->get('jg_msg_download_recipients')), + 'type' => $config->get('jg_msg_download_type') + ) + ); + $this->addMode( array('name' => 'zipdownload', + 'recipients' => explode(',', $config->get('jg_msg_download_recipients')), + 'type' => $config->get('jg_msg_download_type') + ) + ); + $this->addMode( array('name' => 'comment', + 'recipients' => explode(',', $config->get('jg_msg_comment_recipients')), + 'type' => $config->get('jg_msg_comment_type') + ) + ); + $this->addMode( array('name' => 'nametag', + 'recipients' => explode(',', $config->get('jg_msg_nametag_recipients')), + 'type' => $config->get('jg_msg_nametag_type') + ) + ); + $this->addMode( array('name' => 'report', + 'recipients' => explode(',', $config->get('jg_msg_report_recipients')), + 'type' => $config->get('jg_msg_report_type') + ) + ); + $this->_modes['send2friend']['recipients'] = array(); + $this->_modes['send2friend']['type'] = 1; + + $this->_modes['rejectimg']['recipients'] = array(); + $this->_modes['rejectimg']['type'] = $config->get('jg_msg_rejectimg_type'); + + $this->_modes['default'] ['recipients'] = array(); + $this->_modes['default'] ['type'] = 2; + } + + /** + * Method to send a message + * + *
    +   * $message = array(
    +   *                    'recipient' => (int/string) 65 (user ID) || 'localhost@localhost.de (address)
    +   *                    'from'      => (int/string) 65 (user ID) || 'localhost@localhost.de (address)
    +   *                    'fromname'  => (string)     'Username'
    +   *                    'subject'   => (string)     'Subject line'
    +   *                    'body'      => (string)     'Message'
    +   *                    'mode'      => (string)     'upload' || 'comment' || 'send2friend' || ...
    +   *                    'type'      => (int)        0 (global setting according to mode) || 1 (mail) || 2 (msg) || 3 (both)
    +   *                  );
    +   * 
    + * + * @param array $message Array which holds the message data + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + public function send($message) + { + if(!$this->_loadMessage($message)) + { + return false; + } + + // Send message depending of the selected type + $result_array = array(); + if($this->type == 1 || $this->type == 3) + { + $result_array[] = $this->_sendMail(); + } + if($this->type == 2 || $this->type == 3) + { + $result_array[] = $this->_sendMsg(); + } + + if(in_array(false, $result_array, true)) + { + return false; + } + + return true; + } + + /** + * Method to add one ore more recipients for the next delivery + * + * @param array $recipients An array of recipients or a single one as a string + * @return void + * @since 1.5.5 + */ + public function addRecipients($recipients) + { + if(is_array($recipients)) + { + $this->_recipients = array_merge($this->_recipients, $recipients); + } + else + { + $this->_recipients[] = $recipients; + } + } + + /** + * Method to add a message send mode + * + * @param array $mode Holds the data of the additional mode + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + public function addMode($mode) + { + // Only add mode if sufficient information is given + if( !isset($mode['name']) || !($mode['name']) + || !isset($mode['recipients']) || !is_array($mode['recipients']) + || !isset($mode['type']) || !is_numeric($mode['type']) + ) + { + return false; + } + + if( !count($mode['recipients']) + || ($mode['recipients'][0] == '-1' && count($mode['recipients']) == 1) + ) + { + // If array is empty or first element of array is '-1' (Default Recipients) + // we will add all users who have set 'Receive System E-mails' to 'Yes' + static $recipients; + + if(empty($recipients)) + { + $db = JFactory::getDBO(); + $query = $db->getQuery(true) + ->select('id') + ->from('#__users') + ->where('sendEmail = 1'); + $db->setQuery($query); + $recipients = $db->loadColumn(); + } + + $mode['recipients'] = $recipients; + } + else + { + // If first element of array is 0, no certain + // recipient shall get the message by default + // Please add recipients while preparing the message then + if($mode['recipients'][0] == 0 && count($mode['recipients']) == 1) + { + $mode['recipients'] = array(); + } + } + + $name = $mode['name']; + unset($mode['name']); + $this->_modes[$name] = $mode; + + return true; + } + + /** + * Returns the data of a specific message send mode + * + * @param array $mode The key of the requested mode + * @return array An array that holds the data of the requested mode + * @since 1.5.5 + */ + public function getModeData($mode = 'default') + { + if(!isset($this->_modes[$mode])) + { + $mode = 'default'; + } + + return $this->_modes[$mode]; + } + + /** + * Returns the recipients which are currently selected. + * + * Merges the recipients of the currently selected mode and the additional + * recipients added by the method addRecipients(). + * + * @return array An array of recipients + * @since 1.5.5 + */ + public function getRecipients() + { + return array_unique(array_merge($this->_modes[$this->_mode]['recipients'], $this->_recipients)); + } + + /** + * Returns the type of a specific mode. + * + * @param string The mode of which the type is requested + * @return array The requested type, 2 if $mode was false + * @since 1.5.5 + */ + public function getType($mode = false) + { + if($mode) + { + $mode = $this->getModeData($mode); + return $mode['type']; + } + else + { + return 2; + } + } + + /** + * Checks if sufficent information are given to send a message + * and prepares the message for getting sent. + * + * @param array $message Array which should hold all information about the message. + * @return boolean True if message may be sent, false otherwise. + * @since 1.5.5 + */ + protected function _loadMessage($message) + { + if( /*!isset($message['from']) + ||*/ !isset($message['subject']) + || !isset($message['body']) + /*|| empty($message['from'])*/ + || !$message['subject'] + || !$message['body'] + ) + { + JError::raiseNotice(500, 'Unsufficient Information to send message'); + return false; + } + + if(isset($message['recipient']) && $message['recipient']) + { + $this->addRecipients($message['recipient']); + } + + $this->_message = $message; + $this->_subject = $this->_message['subject']; + $this->_text = $this->_message['body']; + + $this->_loadMode(); + + return true; + } + + /** + * Loads the message send mode according to the loaded message. + * + * @return void + * @since 1.5.5 + */ + protected function _loadMode() + { + if(isset($this->_message['mode'])) + { + $this->_mode = $this->_message['mode']; + } + else + { + $this->_mode = 'default'; + } + + if(!array_key_exists($this->_mode, $this->_modes)) + { + JError::raiseError(500, 'Unknown JoomGallery send message mode'); + } + + if(isset($this->_message['type']) && $this->_message['type']) + { + $this->type = $this->_message['type']; + } + else + { + $this->type = $this->getType($this->_mode); + } + } + + /** + * Sends a message as an electronic mail. + * + * @return booelean True on success, JError object otherwise + * @since 1.5.5 + */ + protected function _sendMail() + { + $from = null; + if(!$this->globalfrom && isset($this->_message['from'])) + { + if(is_numeric($this->_message['from'])) + { + $user = JFactory::getUser($this->_message['from']); + + // Ensure that a valid user was selected + if(is_object($user)) + { + $from = $user->get('email'); + } + } + else + { + //if(JMailHelper::isEmailAddress($this->_message['from'])) + //{ + $from = $this->_message['from']; + //} + } + } + if(!$from) + { + $mainframe = JFactory::getApplication('site'); + $from = $mainframe->getCfg('mailfrom'); + } + + if($this->globalfrom || !isset($this->_message['fromname']) || !$this->_message['fromname']) + { + if(!isset($user) || !is_object($user)) + { + $mainframe = JFactory::getApplication('site'); + $fromname = $mainframe->getCfg('fromname'); + } + else + { + $fromname = $this->realname ? $user->get('name') : $user->get('username'); + } + } + else + { + $fromname = $this->_message['fromname']; + } + + $recipients = array(); + foreach($this->getRecipients() as $recipient) + { + if(is_numeric($recipient)) + { + $user = JFactory::getUser($recipient); + + // Ensure that a valid user was selected + if(is_object($user)) + { + $recipients[] = $user->get('email'); + } + } + else + { + $recipients[] = $recipient; + } + } + + // Remove duplicate values + $recipients = array_unique($recipients); + + if(!count($recipients)) + { + // If there aren't any recipients, there is nothing left to do + return true; + } + + $result = false; + + try + { + $mailer = JFactory::getMailer(); + + $mailer->setSubject($this->_subject); + $mailer->setBody($this->_text); + $mailer->isHtml(false); + $mailer->addBcc($recipients); + $mailer->setSender(array($from, $fromname)); + + $result = $mailer->Send(); + } + catch(phpmailerException $ex) + { + return false; + } + + if($result !== true) + { + return false; + } + + return true; + } + + /** + * Sends a message as a personal message (PM). + * + * @return booelean True on success, false otherwise + * @since 1.5.5 + */ + protected function _sendMsg() + { + $db = JFactory::getDBO(); + require_once JPATH_ADMINISTRATOR.'/components/com_messages/tables/message.php'; + + $no_from = false; + if(isset($this->_message['from']) && $this->_message['from'] && is_numeric($this->_message['from'])) + { + $from = $this->_message['from']; + } + else + { + $no_from = true; + + // Try to get the ID of a super administrator + $query = $db->getQuery(true) + ->select('user_id') + ->from('#__user_usergroup_map') + ->where('group_id = 8'); + $db->setQuery($query); + if(!$from = $db->loadResult()) + { + $query->clear() + ->select('id') + ->from('#__users') + ->order('id ASC'); + $db->setQuery($query); + $from = $db->loadResult(); + } + } + + $recipients = array(); + foreach($this->getRecipients() as $recipient) + { + if(is_numeric($recipient)) + { + $recipients[] = $recipient; + } + } + + if(!count($recipients)) + { + // If there aren't any recipients, there is nothing left to do + return true; + } + + // Messaging for new items + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR.'/components/com_messages/models', 'MessagesModel'); + JTable::addIncludePath(JPATH_ADMINISTRATOR.'/components/com_messages/tables'); + + $result_array = array(); + foreach($recipients as $recipient) + { + $message = array( 'from' => $from, + 'recipient' => $recipient, + 'subject' => $this->_subject, + 'text' => $this->_text, + 'mode' => $this->_mode, + 'system' => $no_from + ); + + // Send messages only if all plugins allow that + // A plugin could disallow that if it sends the message via another system, for example. + $plugins = JDispatcher::getInstance()->trigger('onJoomBeforeSendMessage', array($message)); + if(!in_array(false, $plugins, true)) + { + $message['user_id_to'] = $recipient; + $message['user_id_from'] = $from; + $message['message'] = $this->_text; + $msg = JModelLegacy::getInstance('Message', 'MessagesModel'); + $result_array[] = $msg->save($message); + } + } + + if(in_array(false, $result_array)) + { + JError::raiseNotice(500, $msg->getError()); + return false; + } + + return true; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/helpers/routing.php b/deployed/joomgallery/components/com_joomgallery/helpers/routing.php new file mode 100644 index 00000000..99779cb5 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/helpers/routing.php @@ -0,0 +1,97 @@ +getQuery(true) + ->select('cid') + ->from(_JOOM_TABLE_CATEGORIES) + ->where('alias = '.$db->quote(str_replace(':', '-', $path))); + $db->setQuery($query); + if($result = $db->loadResult()) + { + return array('view' => 'category', 'id' => $result); + } + + $count = count($segments); + $query->clear() + ->select('id') + ->from(_JOOM_TABLE_IMAGES) + ->where('alias = '.$db->quote(str_replace(':', '-', $segments[$count-1]))); + $db->setQuery($query); + if($result = $db->loadResult()) + { + return array('view' => 'detail', 'id' => $result); + } + + return false; + } + + /** + * Checks an Itemid whether it is related to the gallery view. + * If not, an Itemid which is related to the gallery view is + * returned, if found. + * + * @param int $Itemid The Itemid to check + * @return int/boolean Found Itemid, false if correct Itemid was not found or passed Itemid is correct + * @since 1.5.5 + */ + public static function checkItemid($Itemid) + { + $mainframe = JApplication::getInstance('site'); + $menu = $mainframe->getMenu(); + $menuItem = $menu->getItem($Itemid); + if(!isset($menuItem->query['view']) || $menuItem->query['view'] == 'gallery') + { + return false; + } + + $db = JFactory::getDBO(); + $query = $db->getQuery(true) + ->select('id') + ->from('#__menu') + ->where('link LIKE '.$db->quote('%option=com_joomgallery&view=gallery%')); + $db->setQuery($query); + $Itemid = intval($db->loadResult()); + + if($Itemid) + { + return $Itemid; + } + + return false; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/index.html b/deployed/joomgallery/components/com_joomgallery/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/interface.php b/deployed/joomgallery/components/com_joomgallery/interface.php new file mode 100644 index 00000000..235af9c6 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/interface.php @@ -0,0 +1,1554 @@ +_mainframe = JFactory::getApplication(); + $this->_db = JFactory::getDBO(); + $this->_ambit = JoomAmbit::getInstance(); + $this->_jg_config = JoomConfig::getInstance(); + $this->_user = JFactory::getUser(); + + // Include language for display + $language = JFactory::getLanguage(); + $language->load(_JOOM_OPTION); + + // Load JoomGallery plugins + JPluginHelper::importPlugin('joomgallery'); + + // Set some default values for options given in global JG config (may be overridden) + $this->_config['showhits'] = $this->_jg_config->get('jg_showhits'); + $this->_config['showdownloads'] = $this->_jg_config->get('jg_showdownloads'); + $this->_config['showpicasnew'] = $this->_jg_config->get('jg_showpicasnew'); + $this->_config['showtitle'] = $this->_jg_config->get('jg_showtitle'); + $this->_config['showauthor'] = $this->_jg_config->get('jg_showauthor'); + $this->_config['showrate'] = $this->_jg_config->get('jg_showcatrate'); + $this->_config['shownumcomments'] = $this->_jg_config->get('jg_showcatcom'); + $this->_config['showdescription'] = $this->_jg_config->get('jg_showcatdescription'); + + $this->_config['openimage'] = $this->_jg_config->get('jg_detailpic_open'); + + // Further defaults (not given by JG config) + // - Category path links to category + $this->_config['showcatlink'] = 1; + // - Comma-separated list of categories to filter from (empty: all categories, default) + $this->_config['categoryfilter'] = ''; + // - Display last comment (see Module JoomImages) not implemented yet! + $this->_config['showlastcomment'] = 0; + // - Make use of hidden images and images in hidden categories + $this->_config['showhidden'] = 0; + + // Store the config for being able to reset it later on (if useful) + $this->storeConfig(); + } + + /** + * Passes a whole array of config items, existing (default) + * values are overwritten if a new item with the same key + * is passed. + * + * @param array $config An array of settings + * @return void + * @since 1.0.0 + */ + public function setConfig($config) + { + foreach($config as $key => $value) + { + $config[$key] = $this->_db->escape($value); + } + // Merge new array into existing one, overwriting if needed: + $this->_config = array_merge($this->_config, $config); + } + + /** + * Sets a single option in the interface settings + * If the key already exists, the setting will be overridden. + * + * @param string $key The key of the new setting + * @param string $value The value of the new setting + * @return void + * @since 1.0.0 + */ + public function addConfig($key, $value = '') + { + $this->_config[$key] = $this->_db->escape($value); + } + + /** + * Requests string (e.g. modification of a SQL query or true/false) + * associated with config option $key. + * If the according value has not been set with addConfig + * before, a default is returned. Config options are not used + * directly for security. + * + * @param string $key The key of the requested setting + * @return string The requested setting, boolean false, if the key was not found + * @since 1.0.0 + */ + public function getConfig($key) + { + if(array_key_exists($key, $this->_config)) + { + // Access filtered to special keys (DB query strings) + if($key == 'hidebackend') + { + if( $this->_config['hidebackend'] == 'true' + || $this->_config['hidebackend'] === true + || $this->_config['hidebackend'] == 1 + ) + { + return 'jg.owner != 0'; + } + else + { + return ''; + } + } + elseif($key == 'categoryfilter') + { + $catids = trim($this->_db->escape($this->_config['categoryfilter'])); + if($catids != '') + { + return 'jg.catid IN ('.$catids.')'; + } + else + { + return ''; + } + } + else + { + // Regular keys + return $this->_config[$key]; + } + } + else + { + return false; + } + } + + /** + * Stores the config in order to be able to reset it later on + * + * @return void + * @since 1.5.0 + */ + public function storeConfig() + { + $this->_storedConfig = $this->_config; + } + + /** + * Resets the config in order to get the settings as they were + * at the point of time when 'storeConfig' was called lastly. + * + * @return void + * @since 1.5.0 + */ + public function resetConfig() + { + $this->_config = $this->_storedConfig; + } + + /** + * Returns config value associated with config option $key + * of the global configuration of JoomGallery. + * + * @param string $key The key of the requested setting + * @return string The requested setting, boolean false, if the key was not found + * @since 1.0.0 + */ + public function getJConfig($key) + { + return $this->_jg_config->get($key); + } + + /** + * Returns the JoomGallery ambit object + * + * @return object JoomAmbit object + * @since 1.5.5 + */ + public function getAmbit() + { + return $this->_ambit; + } + + /** + * Returns version string of installed JoomGallery + * + * @return string The version string + * @since 1.5.0 + */ + public function getGalleryVersion() + { + return '3.3'; + } + + /** + * Returns an Itemid associated with the gallery. + * + * At first check out, if an Itemid was set via the interface, + * if not, take the Itemid provided by JoomAmbit. + * + * @param boolean $string True, if a string like '&Itemid=X' should be returned. + * @return int/string The Itemid for use in URLs ('&Itemid=X' or as integer) + * @since 1.0.0 + */ + public function getJoomId($string = true) + { + if(isset($this->_config['Itemid']) && $this->_config['Itemid']) + { + $Itemid = intval($this->_config['Itemid']); + + return ($string && $Itemid) ? '&Itemid='.$Itemid : $Itemid; + } + else + { + return $this->_ambit->getItemid($string); + } + } + + /** + * Corrects a link with the right 'option' and 'Itemid' vars of JoomGallery + * + * @param string $url The link to complete + * @param boolean $xhtml True, if all '&' appearances shall be replaced with '&', defaults to true + * @return string The corrected link + * @since 1.5.5 + */ + public function route($url, $xhtml = true) + { + // Get the router + $router = $this->_mainframe->getRouter(); + // Get current values of vars 'option' and 'Itemid' + $option = $router->getVar('option'); + $Itemid = $router->getVar('Itemid'); + // Set vars 'option' and 'Itemid' + $router->setVar('option', _JOOM_OPTION); + $router->setVar('Itemid', $this->getJoomId(false)); + + $url = JRoute::_($url, $xhtml); + $routervars = $router->getVars(); + if(is_null($option)) + { + // Delete the var from array + unset($routervars['option']); + } + else + { + $routervars['option'] = $option; + } + if(is_null($Itemid)) + { + unset($routervars['Itemid']); + } + else + { + $routervars['Itemid'] = $Itemid; + } + $router->setVars($routervars, false); + + return $url; + } + + /** + * Simple forwarding of JHTML::_('joomgallery.openimage'): + * Returns the link to the thumb, detail or original image. + * + * @param int/object $img The image ID or the image object to use + * @param string $type The image type ('thumb', 'img', 'orig') + * @return string Link to the image + * @since 1.5.5 + */ + public function getImageLink($img, $type = false) + { + // Get the router + $router = $this->_mainframe->getRouter(); + // Get current values of vars 'option' and 'Itemid' + $option = $router->getVar('option'); + $Itemid = $router->getVar('Itemid'); + + // Set vars 'option' and 'Itemid' + $router->setVar('option', _JOOM_OPTION); + $router->setVar('Itemid', $this->getJoomId(false)); + + $link = JHTML::_('joomgallery.openimage', $this->_config['openimage'], $img, $type, $this->getConfig('group')); + if($title = JHtml::_('joomgallery.getTitleforATag', $img, false)) + { + $link .= '" title="'.$title; + } + + // Reset vars 'option' and 'Itemid' + // if the preserved values are null delete the var formerly setted + // from array of vars + $routervars = $router->getVars(); + if(is_null($option)) + { + // Delete the var from array + unset($routervars['option']); + } + else + { + $routervars['option'] = $option; + } + if(is_null($Itemid)) + { + unset($routervars['Itemid']); + } + else + { + $routervars['Itemid'] = $Itemid; + } + $router->setVars($routervars, false); + + return $link; + } + + /** + * Adds all elements needed to display JoomGallery images + * properly like CSS. The necessary Javascript is included in + * the JoomGallery JHTML function openImage(). + * + * @return void + * @since 1.5.5 + */ + public function getPageHeader() + { + $document = JFactory::getDocument(); + + // Add the CSS file generated from backend settings + $document->addStyleSheet($this->_ambit->getStyleSheet('joom_settings.css')); + + // Add the main CSS file + $document->addStyleSheet($this->_ambit->getStyleSheet('joomgallery.css')); + + // Add the RTL CSS file if an RTL language is used + if(JFactory::getLanguage()->isRTL()) + { + $document->addStyleSheet($this->_ambit->getStyleSheet('joomgallery_rtl.css')); + } + + // Add individual CSS file if it exists + if(file_exists(JPATH_ROOT.'/media/joomgallery/css/joom_local.css')) + { + $document->addStyleSheet($this->_ambit->getStyleSheet('joom_local.css')); + } + } + + /** + * Creates HTML for linked thumbnail of one image, + * with display options and style just like in JG + * + * @param object $obj DB-row coming from this interface, e.g. getPicsByCategory + * @param boolean $linked If true, we will link the thumbnail, defaults to true + * @param string $class Optional, addional css class name which is assigned to the img tag + * @param string $div Optional css class name which is assigned to a div around the img tag + * @param string $extra Optional, adddional HTML code, which is placed in the img tag + * @param string $type Optional, image type the link shall open (thumb, img, orig) + * @return string HTML displaying thumbnail (linked, like configured in JG if $linked = true) + * @since 1.0.0 + */ + public function displayThumb($obj, $linked = true, $class = null, $div = null, $extra = null, $type = false) + { + $output = ''; + if($obj->id != '') + { + // Get the router + $router = $this->_mainframe->getRouter(); + // Get current values of vars 'option' and 'Itemid' + $option = $router->getVar('option'); + $Itemid = $router->getVar('Itemid'); + // Set vars 'option' and 'Itemid' + $router->setVar('option', _JOOM_OPTION); + $router->setVar('Itemid', $this->getJoomId(false)); + + if($div) + { + $output .= '
    '; + } + + if($linked) + { + // Check for link to category + if(isset($this->_config['catlink']) && $this->_config['catlink'] == 1) + { + $link = JRoute::_('index.php?&view=category&catid='.$obj->catid); + } + else + { + $link = JHTML::_('joomgallery.openimage', $this->_config['openimage'], $obj, $type, $this->getConfig('group')); + if($title = JHtml::_('joomgallery.getTitleforATag', $obj, false)) + { + $link .= '" title="'.$title; + } + } + + $output .= ' '; + } + if($class) + { + $class = ' '.$class; + } + if($extra) + { + $extra = ' '.$extra; + } + $output .= ' '.$obj->imgtitle.''; + if($linked) + { + $output .= ' '; + } + if($div) + { + $output .= '
    '; + } + $routervars = $router->getVars(); + if(is_null($option)) + { + // Delete the var from array + unset($routervars['option']); + } + else + { + $routervars['option'] = $option; + } + if(is_null($Itemid)) + { + unset($routervars['Itemid']); + } + else + { + $routervars['Itemid'] = $Itemid; + } + $router->setVars($routervars, false); + } + else + { + $output .= "  \n"; + } + + return $output; + } + + /** + * Creates HTML for linked detail image of one picture-$obj, + * with display options & style just like in JG + * + * @param object $obj DB-row coming from this interface, e.g. getPicsByCategory + * @param boolean $linked If true, we will link the thumbnail, defaults to true + * @param string $class Optional, addional css class name which is assigned to the img tag + * @param string $div Optional css class name which is assigned to a div around the img tag + * @param string $extra Optional, addional HTML code, which is placed in the img tag + * @param string $type Optional, image type the link shall open (thumb, img, orig) + * @return string HTML displaying detail image (linked, like configured in JG if $linked = true) + * @since 1.0.0 + */ + public function displayDetail($obj, $linked = true, $class = null, $div = null, $extra = null, $type = false) + { + $output = ''; + if($obj->id != '') + { + // Get the router + $router = $this->_mainframe->getRouter(); + // Get current values of vars 'option' and 'Itemid' + $option = $router->getVar('option'); + $Itemid = $router->getVar('Itemid'); + // Set vars 'option' and 'Itemid' + $router->setVar('option', _JOOM_OPTION); + $router->setVar('Itemid', $this->getJoomId(false)); + + if($div) + { + $output .= '
    '; + } + if($linked) + { + // Check for link to category + if(isset($this->_config['catlink']) && $this->_config['catlink'] == 1) + { + $link = JRoute::_('index.php?&view=category&catid='.$obj->catid); + } + else + { + $link = JHTML::_('joomgallery.openimage', $this->_config['openimage'], $obj, $type, $this->getConfig('group')); + if($title = JHtml::_('joomgallery.getTitleforATag', $obj, false)) + { + $link .= '" title="'.$title; + } + } + + $output .= ' '; + } + if($class) + { + $class = ' '.$class; + } + if($extra) + { + $extra = ' '.$extra; + } + $output .= ' '.$obj->imgtitle.''; + if($linked) + { + $output .= ' '; + } + if($div) + { + $output .= '
    '; + } + $routervars = $router->getVars(); + if(is_null($option)) + { + // Delete the var from array + unset($routervars['option']); + } + else + { + $routervars['option'] = $option; + } + if(is_null($Itemid)) + { + unset($routervars['Itemid']); + } + else + { + $routervars['Itemid'] = $Itemid; + } + $router->setVars($routervars, false); + } + else + { + $output .= "  \n"; + } + + return $output; + } + + /** + * Creates HTML for description of one image, + * with display options and style just like in JG. + * Adjustments are possible via the interface options. + * + * @param object $obj DB-row coming from this interface, e.g. getPicsByCategory + * @return string HTML of thumb description (like configured in JG or in the interface) + * @since 1.0.0 + */ + public function displayDesc($obj) + { + if($this->getConfig('disable_infos')) + { + return ''; + } + + // Get the router + $router = $this->_mainframe->getRouter(); + // Get current values of vars 'option' and 'Itemid' + $option = $router->getVar('option'); + $Itemid = $router->getVar('Itemid'); + // Set vars 'option' and 'Itemid' + $router->setVar('option', _JOOM_OPTION); + $router->setVar('Itemid', $this->getJoomId(false)); + + $output = "
      \n"; + + if($this->getConfig('showtitle') || $this->getConfig('showpicasnew')) + { + $output .= "
    • "; + if($this->getConfig('showtitle')) + { + $output .= ''.$obj->imgtitle.''; + } + if($this->getConfig('showpicasnew')) + { + $output.= JoomHelper::checkNew($obj->imgdate, $this->_jg_config->get('jg_daysnew'));; + } + $output .= "
    • \n"; + } + + if($this->getConfig('showauthor')) + { + if($obj->imgauthor) + { + $authorowner = $obj->imgauthor; + } + else + { + $authorowner = JHTML::_('joomgallery.displayname', $obj->owner); + } + + $output .= "
    • ".JText::sprintf('COM_JOOMGALLERY_COMMON_AUTHOR_VAR', $authorowner); + $output .= "
    • \n"; + } + + if($this->getConfig('showcategory')) + { + $catpath = + $output .= "
    • "; + + if($this->getConfig('showcatlink')) + { + $catlink = ''.$obj->cattitle + .''; + $output .= JText::sprintf('COM_JOOMGALLERY_COMMON_CATEGORY_VAR',$catlink); + } + else + { + $output .= JText::sprintf('COM_JOOMGALLERY_COMMON_CATEGORY_VAR',$obj->cattitle); + } + $output .= "
    • "; + } + + if($this->getConfig('showhits')) + { + $output .= "
    • ".JText::sprintf('COM_JOOMGALLERY_COMMON_HITS_VAR', $obj->hits)."
    • "; + } + if($this->getConfig('showdownloads')) + { + $output .= "
    • ".JText::sprintf('COM_JOOMGALLERY_COMMON_DOWNLOADS_VAR', $obj->downloads)."
    • "; + } + if($this->getConfig('showrate')) + { + $output .= '
    • '.JHTML::_('joomgallery.rating', $obj, false, 'jg_starrating_cat').'
    • '; + } + if ($this->getConfig('showimgdate')) + { + $output .= '
    • '.JText::sprintf('COM_JOOMGALLERY_COMMON_UPLOAD_DATE', '
      '.JHTML::_('date', $obj->imgdate, JText::_($this->getConfig('dateformat')))).'
    • '; + } + if($this->getConfig('shownumcomments')) + { + $output .='
    • '. JText::sprintf('COM_JOOMGALLERY_COMMON_COMMENTS_VAR', $obj->cmtcount).'
    • '; + } + if($this->getConfig('showdescription') && $obj->imgtext) + { + $output .= '
    • '. JText::sprintf('COM_JOOMGALLERY_COMMON_DESCRIPTION_VAR', $obj->imgtext).'
    • '; + } + if($this->getConfig('showcmtdate') == 1 && !is_null($obj->cmtdate)) + { + $output .= '
    • '.JText::sprintf('COM_JOOMGALLERY_COMMON_COMMENTS_LASTDATE', JHTML::_('date', $obj->cmtdate, JText::_($this->getConfig('dateformat')))).'
    • '; + } + if($this->getConfig('showcmttext') == 1 && !is_null($obj->cmtdate)) + { + // Comment username + if($obj->cmtuserid != 0) + { + $cmtname = JHTML::_('joomgallery.displayname', $obj->cmtuserid); + } + else + { + $cmtname = $obj->cmtname; + } + + // Comment text + $output .= '
    • '.JText::sprintf('COM_JOOMGALLERY_COMMON_COMMENT_WITH_AUTHOR', $cmtname, $obj->cmttext).'
    • '; + } + + $results = $this->_mainframe->triggerEvent('onJoomAfterDisplayThumb', array($obj->id)); + $output .= trim(implode('', $results)); + + $output .= '
    '; + + $routervars = $router->getVars(); + if(is_null($option)) + { + // Delete the var from array + unset($routervars['option']); + } + else + { + $routervars['option'] = $option; + } + if(is_null($Itemid)) + { + unset($routervars['Itemid']); + } + else + { + $routervars['Itemid'] = $Itemid; + } + $router->setVars($routervars, false); + + return $output; + } + + /** + * Creates HTML for the given thumbnails for displaying them like in category view + * + * @param array $rows An array of database objects for the thumbnails + * @return string The HTML output + * @since 1.5.5 + */ + public function displayThumbs($rows) + { + if(empty($rows)) + { + return ''; + } + + $numcols = $this->getConfig('columns'); + if(!$numcols) + { + $numcols = $this->getConfig('default_columns'); + if(!$numcols) + { + $numcols = 2; + } + } + + $elem_width = floor(99 / $numcols); + + $return = ''; + //$return .= "\n".'
    '."\n"; + $return .= '
    '; + $rowcount = 0; + $itemcount = 0; + + foreach($rows as $row) + { + if(($itemcount % $numcols == 0) && ($itemcount != 0)) + { + $return .='
    '."\n"; + $rowcount++; + } + + $return .= '
    '."\n"; + $type = 'img'; + if( (!is_numeric($this->getConfig('openimage')) || $this->getConfig('openimage') > 0) + && ($this->getJConfig('jg_lightboxbigpic') || $this->getConfig('type') == 'img' || $this->getConfig('type') == 'orig') + && file_exists($this->_ambit->getImg('orig_path', $row)) + ) + { + $type = 'orig'; + } + if($this->getConfig('type') == 'img' || $this->getConfig('type') == 'orig') + { + $return .= ' '.$this->displayDetail($row, true, null, 'jg_imgalign_catimgs', null, $type); + } + else + { + $return .= ' '.$this->displayThumb($row, true, null, 'jg_imgalign_catimgs', null, $type); + } + + if(!$this->getConfig('disable_infos')) + { + $return .= '
    '."\n"; + $return .= ' '.$this->displayDesc($row); + $return .= '
    '."\n"; + } + + $return .= '
    '."\n"; + + $itemcount++; + } + + $return.= '
    '."\n";//.'
    '; + + return $return; + } + + /** + * Adds the WHERE conditions for filtering out disallowed images to a query + * + * @param $query object The query to extend + * @param $access array Access levels to filter for, null to use the ones of the current user + * @return void + * @since 2.0 + */ + public function addImageWhere($query, $access = null) + { + $query->where('jgc.published = 1') + ->where('jg.approved = 1') + ->where('jg.published = 1'); + + if(!$access) + { + $catids = array_keys($this->_ambit->getCategoryStructure()); + $query->where('jg.catid IN ('.implode(',', $catids).')'); + $query->where('jg.access IN ('.implode(',', $this->_user->getAuthorisedViewLevels()).')'); + $query->where('jgc.access IN ('.implode(',', $this->_user->getAuthorisedViewLevels()).')'); + } + else + { + $query->where('jg.access IN ('.implode(',', $access).')'); + $query->where('jgc.access IN ('.implode(',', $access).')'); + } + + if(!$this->getConfig('showhidden')) + { + $query->where('jgc.hidden = 0') + ->where('jgc.in_hidden = 0') + ->where('jg.hidden = 0'); + } + + if($categoryfilter = $this->getConfig('categoryfilter')) + { + $query->where($categoryfilter); + } + + if($hidebackend = $this->getConfig('hidebackend')) + { + $query->where($hidebackend); + } + + return $query; + } + + /** + * Returns the number of images of a user + * + * @param int $userId The user ID of the user. + * @param array $access Access levels to filter for, null to use the ones of the current user + * @return int Number of images the user has uploaded + * @since 1.0.0 + */ + public function getNumPicsOfUser($userId, $access = null) + { + $userId = intval($userId); + + $query = $this->_db->getQuery(true) + ->select('COUNT(jg.id)') + ->from(_JOOM_TABLE_IMAGES.' AS jg') + ->leftJoin(_JOOM_TABLE_CATEGORIES.' AS jgc ON jgc.cid = jg.catid') + ->where('jg.owner = '.$userId); + $this->addImageWhere($query, $access); + + $this->_db->setQuery($query); + + return $this->_db->loadResult(); + } + + /** + * Returns the number of pictures a user is tagged in + * + * @param int $userId The ID of the user. + * @param array $access Access levels to filter for, null to use the ones of the current user + * @return int Number of images the user is tagged in + * @since 1.0.0 + */ + public function getNumPicsUserTagged($userId, $access = null) + { + $userId = intval($userId); + + $query = $this->_db->getQuery(true) + ->select('COUNT(jgn.nid)') + ->from(_JOOM_TABLE_NAMESHIELDS.' AS jgn') + ->leftJoin(_JOOM_TABLE_IMAGES.' AS jg ON jgn.npicid = jg.id') + ->leftJoin(_JOOM_TABLE_CATEGORIES.' AS jgc ON jgc.cid = jg.catid') + ->where('jgn.nuserid = '.$userId); + $this->addImageWhere($query, $access); + + $this->_db->setQuery($query); + + return $this->_db->loadResult(); + } + + /** + * Returns the number of images a user has favoured + * + * @param int $userId The ID of the user. + * @param array $access Access levels to filter for, null to use the ones of the current user + * @return int Number of images the user has favoured + * @since 1.0.0 + */ + public function getNumPicsUserFavoured($userId, $access = null) + { + $userId = intval($userId); + + $query = $this->_db->getQuery(true) + ->select('piclist') + ->from(_JOOM_TABLE_USERS) + ->where('uuserid = '.$userId); + + $this->_db->setQuery($query); + $piclist = $this->_db->loadResult(); + + if(!$piclist) + { + return 0; + } + + $query = $this->_db->getQuery(true) + ->select('COUNT(jg.id)') + ->from(_JOOM_TABLE_IMAGES.' AS jg') + ->leftJoin(_JOOM_TABLE_CATEGORIES.' AS jgc ON jgc.cid = jg.catid') + ->where('jg.id IN ('.$piclist.')'); + $this->addImageWhere($query, $access); + + $this->_db->setQuery($query); + + return $this->_db->loadResult(); + } + + /** + * Returns the number of images a user has commented on + * + * @param int $userId The ID of the user. + * @param array $access Access levels to filter for, null to use the ones of the current user + * @return int Number of images the user has commented on + * @since 1.0.0 + */ + public function getNumCommentsUser($userId, $access = null) + { + return $this->getNumComments($access, $userId); + } + + /** + * Returns the total number of comments (published) in the gallery + * + * @param array $access Access levels to filter for, null to use the ones of the current user + * @return int The number of comments published in the gallery + * @since 1.0.0 + */ + public function getNumComments($access = null, $userId = 0) + { + $userId = intval($userId); + + $query = $this->_db->getQuery(true) + ->select('COUNT(cmtid)') + ->from(_JOOM_TABLE_COMMENTS.' AS jgco') + ->leftJoin(_JOOM_TABLE_IMAGES.' AS jg ON jgco.cmtpic = jg.id') + ->leftJoin(_JOOM_TABLE_CATEGORIES.' AS jgc ON jgc.cid = jg.catid') + ->where('jgco.published = 1') + ->where('jgco.approved = 1'); + + if($userId) + { + $query->where('jgco.userid = '.$userId); + } + + $this->addImageWhere($query, $access); + + $this->_db->setQuery($query); + + return $this->_db->loadResult(); + } + + /** + * Returns a query for counting all comments of a specific image. + * This query has to be used as a sub-query in which context jg.id is defined + * + * @return object A JDatabaseQuery object to be used as a sub-query + * @since 2.0 + */ + public function getNumCommentsSubQuery() + { + return $this->_db->getQuery(true) + ->select('COUNT(cmtid)') + ->from(_JOOM_TABLE_COMMENTS.' AS jgcosub') + ->where('cmtpic = jg.id') + ->where('jgcosub.published = 1') + ->where('jgcosub.approved = 1'); + } + + /** + * Returns images of a user + * + * @param int $userId Joomla ID of user + * @param array $access Access levels to filter for, null to use the ones of the current user + * @param string $sorting String for DB sorting + * @param int $numPics Limit number of pictures, leave away to return all + * @param int $limitStart Where to start returning $numPics images + * @return array An array of image objects from the database + * @since 1.0.0 + */ + public function getPicsOfUser($userId, $access = null, $sorting = null, $numPics = null, $limitStart = 0) + { + // Validation + $userId = intval($userId); + + $query = $this->getImagesQuery($access) + ->where('jg.owner = '.$userId); + + if($sorting) + { + $query->order($this->_db->escape($sorting)); + } + + $this->_db->setQuery($query, $limitStart, $numPics); + + return $this->_db->loadObjectList(); + } + + /** + * Returns images a user is tagged in + * + * @param int $userId Joomla ID of user + * @param array $access Access levels to filter for, null to use the ones of the current user + * @param string $sorting String for DB sorting + * @param int $numPics Limit number of pictures, leave away to return all + * @param int $limitStart Where to start returning $numPics pictures + * @return array An array of image objects from the database + * @since 1.0.0 + */ + public function getPicsUserTagged($userId, $access = null, $sorting = null, $numPics = null, $limitStart = 0) + { + // Validation + $userId = intval($userId); + + $query = $this->_db->getQuery(true); + + if($this->getConfig('shownumcomments')) + { + $query->select('('.$this->getNumCommentsSubQuery().') AS cmtcount'); + } + + $query->select('jg.id, jg.catid, jg.imgthumbname, jg.imgfilename, jg.owner, jg.imgauthor, + jg.imgdate, jg.imgtitle, jg.imgtext, jg.hits, jg.downloads, jg.imgvotes, + '.JoomHelper::getSQLRatingClause('jg').' AS rating, + jgc.name AS cattitle, jgc.catpath AS catpath') + ->from(_JOOM_TABLE_NAMESHIELDS.' AS jgn') + ->leftJoin(_JOOM_TABLE_IMAGES. ' AS jg ON jgn.npicid = jg.id') + ->leftJoin(_JOOM_TABLE_CATEGORIES.' AS jgc ON jgc.cid = jg.catid') + ->where('jgn.nuserid = '.$userId); + + if($this->getConfig('showlastcomment')) + { + $query->select('jgco.cmttext, jgco.cmtdate, jgco.userid, jgco.cmtid') + ->leftJoin(_JOOM_TABLE_COMMENTS.' AS jgco ON jg.id = jgco.cmtpic') + ->leftJoin(_JOOM_TABLE_COMMENTS.' AS jgco2 ON jgco.cmtpic = jgco2.cmtpic AND jgco.cmtdate < jgco2.cmtdate') + ->where('jgco2.cmtpic IS NULL'); + } + + $this->addImageWhere($query, $access); + + if($sorting) + { + $query->order($this->_db->escape($sorting)); + } + + $this->_db->setQuery($query, $limitStart, $numPics); + + return $this->_db->loadObjectList(); + } + + /** + * Returns the images a user has favoured + * + * @param int $userId Joomla ID of user + * @param array $access Access levels to filter for, null to use the ones of the current user + * @param string $sorting String for DB sorting + * @param int $numPics Limit number of images, leave away to return all + * @param int $limitStart Where to start returning $numPics images + * @return array An array of image objects from the database + * @since 1.0.0 + */ + public function getPicsUserFavoured($userId, $access = null, $sorting = null, $numPics = null, $limitStart = 0) + { + // Validation + $userId = intval($userId); + + $query = $this->_db->getQuery(true) + ->select('piclist') + ->from(_JOOM_TABLE_USERS) + ->where('uuserid = '.$userId); + + $this->_db->setQuery($query); + $piclist = $this->_db->loadResult(); + + if(!$piclist) + { + return array(); + } + + $query = $this->getImagesQuery($access) + ->where('jg.id IN ('.$piclist.')'); + + if($sorting) + { + $query->order($this->_db->escape($sorting)); + } + + $this->_db->setQuery($query, $limitStart, $numPics); + + return $this->_db->loadObjectList(); + } + + /** + * Returns the comments of a user on images + * + * @param int $userId Joomla ID of user + * @param array $access Access levels to filter for, null to use the ones of the current user + * @param string $sorting String for DB sorting (default: newest by ID) + * @param int $numComments Limit number of images, leave away to return all + * @param int $limitStart Where to start returning $numComments images + * @return array An array of image objects from the database + * @since 1.0.0 + */ + public function getCommentsUser($userId, $access = null, $sorting = 'jgco.cmtid DESC', $numComments = null, $limitStart = 0) + { + return $this->getComments($access, $sorting, $numComments, $limitStart, $userId); + } + + /** + * Returns all (or some ;) ) comments in the gallery as DB-rows + * + * @param array $access Access levels to filter for, null to use the ones of the current user + * @param string $sorting String for DB sorting (default: Newest by ID) + * @param int $numComments Limit number of comments, leave away to return all + * @param int $limitStart Where to start returning $numComments comments + * @param int $userId Joomla ID of user + * @return array An array of comment objects from the database + * @since 1.0.0 + */ + public function getComments($access = null, $sorting = "jgco.cmtid DESC", $numComments = null, $limitStart = 0, $userId = 0) + { + $userId = intval($userId); + + $query = $this->_db->getQuery(true) + ->select('jg.id, jgco.cmttext, jgco.cmtdate, jgco.userid AS cmtuserid') + ->select('jg.catid, jg.imgthumbname, jg.imgfilename, jg.owner, jg.imgauthor, + jg.imgdate, jg.imgtitle, jg.imgtext, jg.hits, jg.downloads, jg.imgvotes, + '.JoomHelper::getSQLRatingClause('jg').' AS rating, + jgc.name AS cattitle, jgc.catpath AS catpath') + ->from(_JOOM_TABLE_COMMENTS.' AS jgco') + ->leftJoin(_JOOM_TABLE_IMAGES.' AS jg ON jgco.cmtpic = jg.id') + ->leftJoin(_JOOM_TABLE_CATEGORIES.' AS jgc ON jgc.cid = jg.catid') + ->where('jgco.published = 1') + ->where('jgco.approved = 1'); + + if($userId) + { + $query->where('jgco.userid = '.$userId); + } + + $this->addImageWhere($query, $access); + + $this->_db->setQuery($query, $limitStart, $numComments); + + return $this->_db->loadObjectList(); + } + + /** + * Returns db-row of one image, with optional access verification + * + * @param int $picid ID of images in gallery + * @param array $access Access levels to filter for, null to use the ones of the current user + * @return object The image object from the database + * @since 1.0.0 + */ + public function getPicture($picid, $access = null) + { + $picid = intval($picid); + + $query = $this->getImagesQuery($access) + ->where('jg.id = '.$picid); + + $this->_db->setQuery($query); + + return $this->_db->loadObject(); + } + + /** + * Returns a query object containing the general data for requesting images data + * + * @param array $access Array of access levels to filter with + * @return object A JDatabaseQuery object + * @since 2.0 + */ + public function getImagesQuery($access = null) + { + $query = $this->_db->getQuery(true); + + if($this->getConfig('shownumcomments')) + { + $query->select('('.$this->getNumCommentsSubQuery().') AS cmtcount'); + } + + $query->select('jg.id, jg.catid, jg.imgthumbname, jg.imgfilename, jg.owner, jg.imgauthor, + jg.imgdate, jg.imgtitle, jg.imgtext, jg.hits, jg.downloads, jg.imgvotes, + '.JoomHelper::getSQLRatingClause('jg').' AS rating, + jgc.name AS cattitle, jgc.catpath AS catpath') + ->from(_JOOM_TABLE_IMAGES.' AS jg') + ->leftJoin(_JOOM_TABLE_CATEGORIES.' AS jgc ON jgc.cid = jg.catid'); + + if($this->getConfig('showlastcomment')) + { + $query->select('jgco.cmttext, jgco.cmtdate, jgco.userid, jgco.cmtid') + ->leftJoin(_JOOM_TABLE_COMMENTS.' AS jgco ON jg.id = jgco.cmtpic') + ->leftJoin(_JOOM_TABLE_COMMENTS.' AS jgco2 ON jgco.cmtpic = jgco2.cmtpic AND jgco.cmtdate < jgco2.cmtdate') + ->where('jgco2.cmtpic IS NULL'); + } + + $this->addImageWhere($query, $access); + + return $query; + } + + /** + * Returns the db-row of a random image, to which a user with has access to + * (e.g. for a simple 1pic module) + * + * @param array $access Access levels to filter for, null to use the ones of the current user + * @return object An image object from the database + * @since 1.0.0 + */ + public function getRandomPicture($access = null) + { + $query = $this->getImagesQuery($access) + ->order('RAND()'); + + $this->_db->setQuery($query); + + return $this->_db->loadObject(); + } + + /** + * Returns the number of images in a category + * + * @param int $catid ID of category + * @param array $access Access levels to filter for, null to use the ones of the current user + * @return int The number of images in the category + * @since 1.0.0 + */ + public function getNumPicsByCategory($catid, $access = null) + { + $catid = intval($catid); + + $query = $this->_db->getQuery(true) + ->select('COUNT(jg.id)') + ->from(_JOOM_TABLE_IMAGES.' AS jg') + ->leftJoin(_JOOM_TABLE_CATEGORIES.' AS jgc ON jgc.cid = jg.catid') + ->where('jg.catid = '.$catid); + + $this->_db->setQuery($query); + + return $this->_db->loadResult(); + } + + /** + * Returns image objects of all images in a category + * + * @param int $catid The ID of the category + * @param array $access Access levels to filter for, null to use the ones of the current user + * @param string $sorting Sorting string + * @param int $numPics Limit number of images, leave away to return all + * @param int $limitStart Where to start returning $numPics images + * @return array An array of comment objects from the database + * @since 1.0.0 + */ + public function getPicsByCategory($catid, $access = null, $sorting = null, $numPics = null, $limitStart = 0) + { + // Validation + $catid = intval($catid); + + $query = $this->getImagesQuery($access) + ->where('jg.catid = '.$catid); + + if($sorting) + { + $query->order($this->_db->escape($sorting)); + } + + $this->_db->setQuery($query, $limitStart, $numPics); + + return $this->_db->loadObjectList(); + } + + /** + * Extends a query by search conditions + * + * @param object $query The query to extend + * @param string $searchstring The string to search for + * @return void + * @since 2.0 + */ + public function addSearchTerms($query, $searchstring) + { + $aliases = array('images' => 'jg', 'categories' => 'jgc'); + $plugins = JDispatcher::getInstance()->trigger('onJoomSearch', array($searchstring, $aliases, _JOOM_OPTION.'.interface')); + + $searchstring = $this->_db->quote('%'.$this->_db->escape(strtolower(trim($searchstring))).'%'); + + $where = '(jg.imgtitle LIKE '.$searchstring.' OR LOWER(jg.imgtext) LIKE '.$searchstring; + + foreach($plugins as $plugin) + { + if(isset($plugin['images.select'])) + { + $query->select($plugin['images.select']); + } + + if(isset($plugin['images.leftjoin'])) + { + $query->leftJoin($plugin['images.leftjoin']); + } + + if(isset($plugin['images.where'])) + { + $query->where($plugin['images.where']); + } + + if(isset($plugin['images.where.or'])) + { + $where .= ' OR '.$plugin['images.where.or']; + } + } + + $query->where($where); + } + + /** + * Returns number of images matching the search string + * (e.g. for pre-filtering, pagination) + * + * @param string $searchstring The string to use for the search + * @param array $access Access levels to filter for, null to use the ones of the current user + * @return int The number of images matching the search string + * @since 1.0.0 + */ + public function getNumPicsBySearch($searchstring, $access = null) + { + $query = $this->_db->getQuery(true) + ->select('COUNT(jg.id)') + ->from(_JOOM_TABLE_IMAGES.' AS jg') + ->leftJoin(_JOOM_TABLE_CATEGORIES.' AS jgc ON jgc.cid = jg.catid'); + $this->addImageWhere($query); + $this->addSearchTerms($query); + + $this->_db->setQuery($query); + + return $this->_db->loadResult(); + } + + /** + * Returns db-rows of images matching the search string + * E.g. useful for a search mambot + * + * @param string $searchstring The string to use for the search + * @param array $access Access levels to filter for, null to use the ones of the current user + * @param string $sorting Sorting string + * @param int $numPics Limit number of images, leave away to return all + * @param int $limitStart Where to start returning $numPics images + * @return array An array of image objects from the database + * @since 1.0.0 + */ + public function getPicsBySearch($searchstring, $access = null, $sorting = null, $numPics = null, $limitStart = 0) + { + $query = $this->getImagesQuery($access); + + $this->addSearchTerms($query, $searchstring); + + if($sorting) + { + $query->order($this->_db->escape($sorting)); + } + + $this->_db->setQuery($query, $limitStart, $numPics); + + return $this->_db->loadObjectList(); + } + + /** + * Creates a new category out of the information of the given object + * + * @param object $obj Should hold all the information about the new category + * @param int The ID of the new category, false, if an error occured + * @since 1.5.0 + */ + public function createCategory($obj) + { + jimport('joomla.filesystem.file'); + JLoader::register('JoomFile', JPATH_ADMINISTRATOR.'/components/'._JOOM_OPTION.'/helpers/file.php'); + + $row = JTable::getInstance('joomgallerycategories', 'Table'); + $row->bind($obj); + + if(!$row->name) + { + $this->_mainframe->enqueueMessage(JText::_('No valid category name given'), 'error'); + + return false; + } + + $row->parent_id = (int) $row->parent_id; + if($row->parent_id < 1) + { + $row->parent_id = 1; + } + + // Determine location in category tree + if(!isset($obj->ordering) || !$obj->ordering || $obj->ordering == 'first-child') + { + $row->setLocation($row->parent_id, 'first-child'); + } + else + { + if($obj->ordering == 'last-child') + { + $row->setLocation($row->parent_id, 'last-child'); + } + else + { + $row->setLocation($obj->ordering, 'after'); + } + } + + // Ensure that the data is valid + if(!$row->check()) + { + $this->_mainframe->enqueueMessage($row->getError(), 'error'); + + return false; + } + + // Store the data in the database + if(!$row->store()) + { + $this->_mainframe->enqueueMessage($row->getError(), 'error'); + + return false; + } + + // Now we have the ID of the new category + // and the catpath can be built + $row->catpath = JoomFile::fixFilename($row->name).'_'.$row->cid; + if($row->parent_id > 1) + { + $row->catpath = JoomHelper::getCatPath($row->parent_id).$row->catpath; + } + // So store again, but afore let's create the alias + $row->check(); + if(!$row->store()) + { + $this->_mainframe->enqueueMessage($row->getError(), 'error'); + + return false; + } + + // Create necessary folders and files + $origpath = JPATH_ROOT.'/'.$this->_jg_config->get('jg_pathoriginalimages').$row->catpath; + $imgpath = JPATH_ROOT.'/'.$this->_jg_config->get('jg_pathimages').$row->catpath; + $thumbpath = JPATH_ROOT.'/'.$this->_jg_config->get('jg_paththumbs').$row->catpath; + $result = array(); + $result[] = JFolder::create($origpath); + $result[] = JoomFile::copyIndexHtml($origpath); + $result[] = JFolder::create($imgpath); + $result[] = JoomFile::copyIndexHtml($imgpath); + $result[] = JFolder::create($thumbpath); + $result[] = JoomFile::copyIndexHtml($thumbpath); + + if(in_array(false, $result)) + { + // Delete the just stored database entry + $row->delete(); + + return false; + } + else + { + // New category successfully created + return $row->cid; + } + } + + /** + * Is automatically called when an unknown method is called. + * This will happen if JoomGallery is not uptodate. + * + * @param string $name Name of the unknown method + * @param array $params Array of parameters given to the unknown method + * @return void + * @since 1.5.0 + */ + public function __call($name, $params) + { + $this->_mainframe->enqueueMessage('JoomGallery is not uptodate. Function '.$name.' does not exist', 'error'); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/joomgallery.php b/deployed/joomgallery/components/com_joomgallery/joomgallery.php new file mode 100644 index 00000000..8b4b0ee4 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/joomgallery.php @@ -0,0 +1,44 @@ +execute(JFactory::getApplication()->input->get('task')); + +// Redirect if set by the controller +$controller->redirect(); \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/model.php b/deployed/joomgallery/components/com_joomgallery/model.php new file mode 100644 index 00000000..4e8f0303 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/model.php @@ -0,0 +1,70 @@ +_ambit = JoomAmbit::getInstance(); + $this->_config = JoomConfig::getInstance(); + + $this->_mainframe = JFactory::getApplication('site'); + $this->_user = JFactory::getUser(); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/models/categories.php b/deployed/joomgallery/components/com_joomgallery/models/categories.php new file mode 100644 index 00000000..26f1f018 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/models/categories.php @@ -0,0 +1,162 @@ +filter_fields = array( + 'cid', 'c.cid', + 'name', 'c.name', + 'alias', 'c.alias', + 'parent_id', 'c.parent_id', + 'published', 'c.published', + 'access', 'c.access', 'access_level', + 'owner', 'c.owner', + 'lft', 'c.lft', + 'rgt', 'c.rgt', + 'level', 'c.level' + ); + } + + /** + * Method for retreiving categories allowed for a certain action + * + * @param string $action Optional action to check the categories against + * @param int $filter Optional category ID which will be filtered out together with its sub-categories + * @param string $searchstring Optional string for searching specific categories (name of category will be used for searching) + * @param int $limitstart Optional limit start parameter for database query + * @return array A result set with an array of categories and indicator whether there are more results left on success, Exception object otherwise + * @since 2.1 + */ + public function getAllowedCategories($action = null, $filter = null, $searchstring = '', $limitstart = 0, $current = 0) + { + JHtml::addIncludePath(JPATH_COMPONENT_ADMINISTRATOR.'/helpers/html'); + + // Initialise variables + $results = array('results' => array()); + + $action2 = false; + if($action == 'joom.upload') + { + $action2 = 'joom.upload.inown'; + } + if($action == 'core.create') + { + $action2 = 'joom.create.inown'; + } + if($action == 'core.edit') + { + $action2 = 'core.edit.own'; + } + + $filtered = array(); + if($filter) + { + $filtered = JoomHelper::getAllSubCategories($filter, true, true, true, false); + } + + try + { + // Create the search query + $query = $this->_db->getQuery(true) + ->select('cid, name, owner') + ->from($this->_db->qn(_JOOM_TABLE_CATEGORIES)) + ->where('cid != 1') + ->order('lft'); + if($searchstring) + { + $searchstring = $this->_db->q('%'.$searchstring.'%'); + $query->where('name LIKE '.$searchstring); + } + + // Load all results + $this->_db->setQuery($query); + $result = $this->_db->loadObjectList(); + + // Check the results starting from limit start + $count = count($result); + $j = 0; + + if( !$limitstart + && ($current == 0 || !$action || ($action == 'core.create' && $this->_user->authorise($action, _JOOM_OPTION))) + ) + { + $none = new stdclass(); + $none->cid = 0; + $none->name = JText::_('COM_JOOMGALLERY_COMMON_NO_CATEGORY'); + $none->path = ''; + $none->none = true; + $results['results'][$j] = $none; + $j++; + } + + for($i = $limitstart; $i < $count; $i++) + { + if(in_array($result[$i]->cid, $filtered)) + { + continue; + } + + if( $result[$i]->cid != $current + && $action && !$this->_user->authorise($action, _JOOM_OPTION.'.category.'.$result[$i]->cid) + && ( !$action2 + || !$result[$i]->owner + || $result[$i]->owner != $this->_user->get('id') + || !$this->_user->authorise($action2, _JOOM_OPTION.'.category.'.$result[$i]->cid) + ) + ) + { + continue; + } + + // Stop as soon as we have 10 results. + // This check is done not earlier than at this point because + // we want to know whether there is at least one more result. + if($j == 10) + { + // If 'more' is set a 'More Results' link will be displayed in the view + $results['more'] = $i; + break; + } + + $results['results'][$j] = $result[$i]; + $results['results'][$j]->path = JHtml::_('joomgallery.categorypath', $result[$i]->cid, false, ' » ', false, false, true); + $j++; + } + } + catch(JDatabaseException $e) + { + return $e; + } + + return $results; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/models/category.php b/deployed/joomgallery/components/com_joomgallery/models/category.php new file mode 100644 index 00000000..8b027775 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/models/category.php @@ -0,0 +1,782 @@ +setId($id); + } + + /** + * Method to set the category identifier + * + * @param int $id The Category ID + * @return void + * @since 1.5.5 + */ + public function setId($id) + { + // Set new category ID if valid and wipe data + if(!$id) + { + $this->_mainframe->redirect(JRoute::_('index.php?view=gallery', false), JText::_('COM_JOOMGALLERY_COMMON_NO_CATEGORY_SPECIFIED'), 'notice'); + } + + $this->_id = $id; + $this->_category = null; + $this->_categories = null; + $this->_totalcategories = null; + $this->_categorieswithoutempty = null; + $this->_totalcategorieswithoutempty = null; + $this->_images = null; + $this->_totalimages = null; + } + + /** + * Method to get the data of the current category + * + * @return object An object with the category data + * @since 1.5.5 + */ + public function getCategory() + { + if($this->_loadCategory()) + { + return $this->_category; + } + + return false; + } + + /** + * Retrieves the data of all sub-categories + * + * @return array Array of objects containing the categories data from the database + * @since 1.5.5 + */ + public function getCategories() + { + if($this->_loadCategories()) + { + return $this->_categories; + } + + return array(); + } + + /** + * Method to get the total number of categories + * + * @return int The total number of categories + * @since 1.5.5 + */ + public function getTotalCategories() + { + // Let's load the categories if they doesn't already exist + if(empty($this->_totalcategories)) + { + $query = $this->_buildCategoriesQuery(); + $this->_totalcategories = $this->_getListCount($query); + } + + return $this->_totalcategories; + } + + /** + * Returns the array of all available sub-categories + * of the the current category without empty categories + * + * @return array Categories objects array + * @since 1.5.7 + */ + public function getCategoriesWithoutEmpty() + { + if($this->_loadCategoriesWithoutEmpty()) + { + // We still have to select the categories according to the pagination + $limit = $this->_config->get('jg_subperpage'); + $limitstart = JRequest::getInt('catlimitstart', 0); + $cats = array_slice($this->_categorieswithoutempty, $limitstart, $limit); + + return $cats; + } + + return array(); + } + + /** + * Method to get the total number of categories without empty categories + * + * @return int The total number of categories without empty ones + * @since 1.5.7 + */ + public function getTotalCategoriesWithoutEmpty() + { + // Let's calculate the number if it doesn't already exist + if(empty($this->_totalcategorieswithoutempty)) + { + if(!$this->_loadCategoriesWithoutEmpty()) + { + return 0; + } + } + + return $this->_totalcategorieswithoutempty; + } + + /** + * Retrieves the data of all images of the current category + * + * @return array Array of objects containing the images data from the database + * @since 1.5.5 + */ + public function getImages() + { + if($this->_loadImages()) + { + return $this->_images; + } + + return array(); + } + + /** + * Retrieves the id from the first image of a category + * needed for Option 'Skip category view' + * + * @param int category id + * @return int id of detail image + * @since 2.0 + */ + public function getImageCat($catId) + { + $authorisedViewLevels = implode(',', $this->_user->getAuthorisedViewLevels()); + + $query = $this->_db->getQuery(true) + ->select('id') + ->from(_JOOM_TABLE_IMAGES.' AS a') + ->leftJoin(_JOOM_TABLE_CATEGORIES.' AS c ON c.cid = a.catid') + ->where('a.published = 1') + ->where('a.catid = '.$catId) + ->where('a.approved = 1') + ->where('a.hidden = 0') + ->where('a.access IN ('.$authorisedViewLevels.')') + ->where('c.access IN ('.$authorisedViewLevels.')'); + if($this->_config->get('jg_firstorder')) + { + $query->order('a.'.$this->_config->get('jg_firstorder')); + } + if($this->_config->get('jg_secondorder')) + { + $query->order('a.'.$this->_config->get('jg_secondorder')); + } + if($this->_config->get('jg_thirdorder')) + { + $query->order('a.'.$this->_config->get('jg_thirdorder')); + } + + $this->_db->setQuery($query); + $img = $this->_db->loadResult(); + + return $img; + } + + /** + * Method to get the total number of images + * + * @return int The total number of images + * @since 1.5.5 + */ + public function getTotalImages() + { + // Let's load the categories if they doesn't already exist + if(empty($this->_totalimages)) + { + $query = $this->_buildImagesQuery(); + $this->_totalimages = $this->_getListCount($query); + } + + return $this->_totalimages; + } + + /** + * Retrieves the data of all images of the current category and its sub-categories + * + * @return array Array of objects containing the images data from the database + * @since 1.5.7 + */ + public function getAllImages() + { + if($this->_loadAllImages()) + { + return $this->_allimages; + } + + return array(); + } + + /** + * Method to get one image selected by chance + * + * @return object An object with the data of the selected image + * @since 1.5.5 + */ + public function getRandomImage($catid = 0, $random_catid = 0) + { + $authorisedViewLevels = implode(',', $this->_user->getAuthorisedViewLevels()); + + $query = $this->_db->getQuery(true) + ->select('*, c.access') + ->from(_JOOM_TABLE_IMAGES.' AS p') + ->leftJoin(_JOOM_TABLE_CATEGORIES.' AS c ON c.cid = p.catid'); + if($this->_config->get('jg_showrandomcatthumb') == 1) + { + $query->where('p.catid = '.$catid); + } + else + { + if($this->_config->get('jg_showrandomcatthumb') >= 2) + { + $query->where('p.catid = '.$random_catid); + } + } + $query->where('p.access IN ('.$authorisedViewLevels.')') + ->where('p.published = 1') + ->where('p.approved = 1') + ->where('c.access IN ('.$authorisedViewLevels.')') + ->where('c.published = 1'); + + $this->_db->setQuery($query); + if(!$rows = $this->_db->loadObjectList()) + { + return false; + } + + $row = $rows[mt_rand(0, count($rows) - 1)]; + + return $row; + } + + /** + * Method to unlock a password protected category + * + * @param int $catid ID of the category to unlock + * @param string $password Password of the category to check + * @return boolean True on success, false otherwise + * @since 3.1 + */ + public function unlock($catid, $password) + { + $query = $this->_db->getQuery(true) + ->select('cid, password') + ->from($this->_db->quoteName(_JOOM_TABLE_CATEGORIES)) + ->where('cid = '.(int) $catid); + $this->_db->setQuery($query); + + if(!$category = $this->_db->loadObject()) + { + throw new Exception($this->_db->getErrorMsg()); + } + + if(!$category->password) + { + throw new Exception('Category is not protected.'); + } + + $match = false; + if(substr($category->password, 0, 4) == '$2y$') + { + // BCrypt passwords are always 60 characters, but it is possible that salt is appended although non standard. + $password60 = substr($category->password, 0, 60); + + if(JCrypt::hasStrongPasswordSupport()) + { + $match = password_verify($password, $password60); + } + } + else + { + if(substr($category->password, 0, 8) == '{SHA256}') + { + // Check the password + $parts = explode(':', $category->password); + $crypt = $parts[0]; + $salt = @$parts[1]; + $testcrypt = JUserHelper::getCryptedPassword($password, $salt, 'sha256', false); + + if($category->password == $testcrypt) + { + $match = true; + } + } + else + { + // Check the password + $parts = explode(':', $category->password); + $crypt = $parts[0]; + $salt = @$parts[1]; + + $testcrypt = JUserHelper::getCryptedPassword($password, $salt, 'md5-hex', false); + + if($crypt == $testcrypt) + { + $match = true; + } + } + } + + if(!$match) + { + throw new Exception(JText::_('COM_JOOMGALLERY_CATEGORY_WRONG_PASSWORD')); + } + + $categories = $this->_mainframe->getUserState('joom.unlockedCategories', array(0)); + $categories = array_unique(array_merge($categories, array($catid))); + $this->_mainframe->setUserState('joom.unlockedCategories', $categories); + + return true; + } + + /** + * Method to load the data of the current category + * + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + protected function _loadCategory() + { + // Check whether the requested category exists and + // whether the current user is allowed to see it + $allowed = true; + $categories = $this->_ambit->getCategoryStructure(); + if(!isset($categories[$this->_id])) + { + $allowed = false; + } + + // Let's load the data if it doesn't already exist + if(empty($this->_category)) + { + $query = $this->_db->getQuery(true) + ->select('cid, name, parent_id, description, password, owner, metakey, metadesc, params') + ->from(_JOOM_TABLE_CATEGORIES) + ->where('cid = '.$this->_id) + ->where('published = 1') + ->where('access IN ('.implode(',', $this->_user->getAuthorisedViewLevels()).')'); + + $this->_db->setQuery($query); + + if(!$row = $this->_db->loadObject()) + { + JError::raiseError(500, JText::sprintf('Category with ID %d not found', $this->_id)); + } + + $this->_category = $row; + } + + if(!$allowed) + { + $this->_category->protected = true; + if( (!$this->_category->password || in_array($this->_id, $this->_mainframe->getUserState('joom.unlockedCategories', array(0)))) + && $this->_category->parent_id > 1 + && !isset($categories[$this->_category->parent_id])) + { + JError::raiseError(500, JText::sprintf('Category with ID %d not found', $this->_id)); + } + } + + return true; + } + + /** + * Method to load the data of all sub-categories + * + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + protected function _loadCategories() + { + // Let's load the data if it doesn't already exist + if(empty($this->_categories)) + { + // Get the pagination request variables + $limit = $this->_config->get('jg_subperpage');#JRequest::getVar('limit', 0, '', 'int'); + $limitstart = JRequest::getInt('catlimitstart', 0); + + $query = $this->_buildCategoriesQuery(); + + if(!$rows = $this->_getList($query, $limitstart, $limit)) + { + return false; + } + + $this->_categories = $rows; + } + + return true; + } + + /** + * Loads the data of all available categories from the database + * and checks whether the categories are empty. + * This method stores only the categories which aren't empty after that. + * + * @return boolean True on success, false otherwise + * @since 1.5.7 + */ + private function _loadCategoriesWithoutEmpty() + { + // Let's load the data if it doesn't already exist + if(empty($this->_categorieswithoutempty)) + { + $query = $this->_buildCategoriesQuery(); + if(!$cats = $this->_getList($query)) + { + return false; + } + + foreach($cats as $key => $cat) + { + // Get all sub-categories for each category which contain images + $subcategories = JoomHelper::getAllSubCategories($cat->cid, true); + if(!count($subcategories)) + { + unset($cats[$key]); + } + } + + $this->_categorieswithoutempty = $cats; + $this->_totalcategorieswithoutempty = count($cats); + } + + return true; + } + + /** + * Method to load the data of all images of the current category + * + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + protected function _loadImages() + { + // Let's load the data if it doesn't already exist + if(empty($this->_images)) + { + // Get the pagination request variables + $limitstart = JRequest::getInt('limitstart', 0); + if($limitstart == -1) + { + // If we want to display all images in a popup box we will need all images + $limit = null; + } + else + { + $limit = JRequest::getInt('limit', 0); + } + + $query = $this->_buildImagesQuery(); + + if(!$rows = $this->_getList($query, $limitstart, $limit)) + { + return false; + } + + $this->_images = $rows; + } + + return true; + } + + /** + * Method to load the data of all images of the current category and its sub-categories + * + * @return boolean True on success, false otherwise + * @since 1.5.7 + */ + protected function _loadAllImages() + { + // Let's load the data if it doesn't already exist + if(empty($this->_allimages)) + { + $limit = JRequest::getInt('limit', 0); + + if(!$limit) + { + // RSS in category view is disabled + return false; + } + + if($limit < 0) + { + // If $limit is negative all images will be loaded + $limit = null; + } + + $catids = JoomHelper::getAllSubCategories($this->_id, true); + + $authorisedViewLevels = implode(',', $this->_user->getAuthorisedViewLevels()); + + $query = $this->_db->getQuery(true) + ->select('*, a.owner AS owner') + ->from(_JOOM_TABLE_IMAGES.' AS a') + ->leftJoin(_JOOM_TABLE_CATEGORIES.' AS c ON c.cid = a.catid') + ->where('c.cid IN ('.implode(',', $catids).')') + ->where('a.published = 1') + ->where('a.approved = 1') + ->where('a.hidden = 0') + ->where('a.access IN ('.$authorisedViewLevels.')') + ->where('c.published = 1') + ->where('c.access IN ('.$authorisedViewLevels.')') + ->where('c.hidden = 0') + ->order('a.imgdate DESC'); + + if(!$rows = $this->_getList($query, 0, $limit)) + { + return false; + } + + $this->_allimages = $rows; + } + + return true; + } + + /** + * Returns the query for loading the categories + * + * @return string The query to be used to retrieve the categories data from the database + * @since 1.5.5 + */ + protected function _buildCategoriesQuery() + { + $query = $this->_db->getQuery(true) + ->select('c.*') + ->from(_JOOM_TABLE_CATEGORIES.' AS c'); + + // Join over the images if necessary + if($this->_config->get('jg_showsubthumbs') == 1 || $this->_config->get('jg_showsubthumbs') == 3) + { + $query->select('i.id, i.catid, i.imgthumbname, i.hidden AS imghidden') + ->leftJoin(_JOOM_TABLE_IMAGES.' AS i ON ( c.thumbnail = i.id + AND i.published = 1 + AND i.approved = 1 + AND i.access IN ('.implode(',', $this->_user->getAuthorisedViewLevels()).'))'); + } + + $query->where('c.published = 1') + ->where('c.hidden = 0') + ->where('c.parent_id = '.$this->_id); + + if(!$this->_config->get('jg_showrestrictedcats')) + { + $query->where('c.access IN ('.implode(',', $this->_user->getAuthorisedViewLevels()).')'); + } + + if($this->_config->get('jg_hideemptycats')) + { + $query->where(' (((SELECT COUNT(id) FROM '._JOOM_TABLE_IMAGES.' AS i WHERE i.catid = c.cid) != 0) + OR + ((SELECT COUNT(cid) FROM '._JOOM_TABLE_CATEGORIES.' AS sc WHERE sc.parent_id = c.cid) != 0))'); + } + + if($this->_config->get('jg_ordersubcatbyalpha')) + { + $query->order('c.name'); + } + else + { + $query->order('c.lft ASC'); + } + + return $query; + } + + /** + * Returns the query for loading the images + * + * @return object The query to be used to retrieve the images data from the database + * @since 1.5.5 + */ + protected function _buildImagesQuery() + { + $authorisedViewLevels = implode(',', $this->_user->getAuthorisedViewLevels()); + + $query = $this->_db->getQuery(true) + ->select('*, a.owner AS owner, '.JoomHelper::getSQLRatingClause('a').'AS rating'); + if($this->_config->get('jg_showcatcom')) + { + $subquery = $this->_db->getQuery(true) + ->select('COUNT(cmtid)') + ->from(_JOOM_TABLE_COMMENTS) + ->where('cmtpic = a.id') + ->where('published = 1') + ->where('approved = 1'); + + $query->select('('.$subquery.') AS comments'); + } + $query->from(_JOOM_TABLE_IMAGES.' AS a') + ->leftJoin(_JOOM_TABLE_CATEGORIES.' AS c ON c.cid = a.catid') + ->where('a.published = 1') + ->where('a.catid = '.$this->_id) + ->where('a.approved = 1') + ->where('a.hidden = 0') + ->where('a.access IN ('.$authorisedViewLevels.')') + ->where('c.access IN ('.$authorisedViewLevels.')'); + if($this->_config->get('jg_firstorder')) + { + $query->order('a.'.$this->_config->get('jg_firstorder')); + } + if($this->_config->get('jg_secondorder')) + { + $query->order('a.'.$this->_config->get('jg_secondorder')); + } + if($this->_config->get('jg_thirdorder')) + { + $query->order('a.'.$this->_config->get('jg_thirdorder')); + } + if($this->_config->get('jg_usercatorder')) + { + $user_orderby = $this->_mainframe->getUserStateFromRequest('joom.category.images.orderby', 'orderby'); + $user_orderdir = $this->_mainframe->getUserStateFromRequest('joom.category.images.orderdir', 'orderdir'); + + $orderby = ''; + switch($user_orderby) + { + case 'user': + $orderby = 'a.owner'; + break; + case 'date': + $orderby = 'a.imgdate'; + break; + case 'rating': + $orderby = 'rating'; + break; + case 'title': + $orderby = 'a.imgtitle'; + break; + case 'hits': + $orderby = 'a.hits'; + break; + default: + // Use selected ordering above + break; + } + if( $user_orderby == 'title' + || $user_orderby == 'hits' + || $user_orderby == 'user' + || $user_orderby == 'date' + || $user_orderby == 'rating' + ) + { + if($user_orderdir == 'desc') + { + $orderby .= ' DESC'; + } + else + { + if($user_orderdir == 'asc') + { + $orderby .= ' ASC'; + } + } + } + if($user_orderby == 'rating') + { + $orderby .= ', imgvotesum DESC'; + } + + if(!empty($orderby)) + { + $query->clear('order'); + $query->order($orderby); + } + } + + return $query; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/models/comments.php b/deployed/joomgallery/components/com_joomgallery/models/comments.php new file mode 100644 index 00000000..5a04f552 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/models/comments.php @@ -0,0 +1,305 @@ +setId($id); + } + + /** + * Method to set the image ID + * + * @param int Image ID number + * @since 1.5.5 + */ + public function setId($id) + { + // Set new image ID if valid + if(!$id) + { + JError::raiseError(500, JText::_('COM_JOOMGALLERY_COMMON_NO_IMAGE_SPECIFIED')); + } + $this->_id = $id; + } + + /** + * Method to get the image ID + * + * @return int The image ID + * @since 1.5.5 + */ + public function getId() + { + return $this->_id; + } + + /** + * Method to save a new comment + * + * @return int 1 on success, 2 on success but approval necessary, boolean false otherwise + * @since 1.5.5 + */ + public function save() + { + // Check for hacking attempt + $authorised_viewlevels = implode(',', $this->_user->getAuthorisedViewLevels()); + + $query = $this->_db->getQuery(true) + ->select('c.cid') + ->from(_JOOM_TABLE_IMAGES.' AS a') + ->leftJoin(_JOOM_TABLE_CATEGORIES.' AS c ON c.cid = a.catid') + ->where('a.published = 1') + ->where('a.approved = 1') + ->where('a.id = '.$this->_id) + ->where('a.access IN ('.$authorised_viewlevels.')') + ->where('c.access IN ('.$authorised_viewlevels.')'); + + $this->_db->setQuery($query); + $result = $this->_db->loadResult(); + if( !$result + || !$this->_config->get('jg_showcomment') + || (!$this->_config->get('jg_anoncomment') && !$this->_user->get('id')) + ) + { + die('Hacking attempt, aborted!'); + } + + $categories = $this->_ambit->getCategoryStructure(); + if(!isset($categories[$result])) + { + die('Hacking attempt, aborted!'); + } + + // Comment text + $filter = JFilterInput::getInstance(); + $text = trim($filter->clean(JRequest::getVar('cmttext', '', 'post'))); + if(!$text) + { + $this->_mainframe->redirect(JRoute::_('index.php?view=detail&id='.$this->_id.'#joomcommentform', false), + JText::_('COM_JOOMGALLERY_NO_COMMENT_ENTERED'), 'notice'); + } + + // Name of the one who comments + if($this->_user->get('id')) + { + $name = $this->_config->get('jg_realname') ? $this->_user->get('name') : $this->_user->get('username'); + } + else + { + if($this->_config->get('jg_namedanoncomment')) + { + $name = trim($filter->clean(JRequest::getVar('cmtname', '', 'post'))); + if(!$name) + { + $name = JText::_('COM_JOOMGALLERY_COMMON_GUEST'); + } + } + else + { + $name = JText::_('COM_JOOMGALLERY_COMMON_GUEST'); + } + } + + // Store the data in session + $this->_mainframe->setUserState('joom.comments.name', $name); + $this->_mainframe->setUserState('joom.comments.text', $text); + + // Captcha + $valid = true; + $plugins = $this->_mainframe->triggerEvent('onJoomCheckCaptcha'); + foreach($plugins as $key => $result) + { + if(is_array($result) && isset($result['valid']) && !$result['valid']) + { + $valid = false; + if(isset($result['error']) && $result['error']) + { + $msg = $result['error']; + } + else + { + $msg = JText::_('COM_JOOMGALLERY_DETAIL_MSG_COMMENT_SECURITY_CODE_WRONG'); + } + break; + } + } + + if(!$valid) + { + $this->_mainframe->redirect(JRoute::_('index.php?view=detail&id='.$this->_id.'#joomcommentform', false), + $msg, 'notice'); + } + + // Check whether the comment has to be approved by administrators + if( (!$this->_config->get('jg_approvecom') && $this->_user->get('id')) + || (!$this->_config->get('jg_anonapprovecom') && !$this->_user->get('id')) + ) + { + $approved = 1; + + // Load image data + $image = $this->getTable('joomgalleryimages'); + $image->load($this->_id); + + // Message about new comment to image owner + // If comments have to be approved by administrators + // this message will be sent as soon as the comment was approved + if( $this->_config->get('jg_msg_comment_toowner') + && $image->owner + && $image->owner != $this->_user->get('id') + ) + { + // Load image data + $row = $this->getTable('joomgalleryimages'); + $row->load($this->_id); + + require_once(JPATH_COMPONENT.'/helpers/messenger.php'); + $messenger = new JoomMessenger(); + $message = array( + 'from' => $this->_user->get('id'), + 'recipient' => $image->owner, + 'subject' => JText::_('COM_JOOMGALLERY_MESSAGE_NEW_COMMENT_TO_OWNER_SUBJECT'), + 'body' => JText::sprintf('COM_JOOMGALLERY_MESSAGE_NEW_COMMENT_TO_OWNER_BODY', $name, $image->imgtitle, $this->_id), + 'type' => $messenger->getType('comment') + ); + } + } + else + { + $approved = 0; + + // Message about new comment + require_once(JPATH_COMPONENT.'/helpers/messenger.php'); + $messenger = new JoomMessenger(); + + $message = array( + 'from' => $this->_user->get('id'), + 'subject' => JText::_('COM_JOOMGALLERY_MESSAGE_NEW_COMMENT_SUBJECT'), + 'body' => JText::sprintf('COM_JOOMGALLERY_MESSAGE_NEW_COMMENT_BODY', $name), + 'mode' => 'comment' + ); + } + + // Change \r\n or \n to
    + $text = nl2br(stripcslashes($text)); + $date = JFactory::getDate(); + $row = $this->getTable('joomgallerycomments'); + + $row->cmtpic = $this->_id; + $row->cmtip = $_SERVER['REMOTE_ADDR']; + $row->userid = $this->_user->get('id'); + $row->cmtname = $name; + $row->cmttext = $text; + $row->cmtdate = $date->toSQL(); + $row->published = 1; + $row->approved = $approved; + + // Trigger event 'onJoomBeforeComment' + $plugins = $this->_mainframe->triggerEvent('onJoomBeforeComment', array(&$row)); + if(in_array(false, $plugins, true)) + { + return false; + } + + if(!$row->check()) + { + $this->setError($row->getError()); + + return false; + } + + if(!$row->store()) + { + $this->setError(JText::_('COM_JOOMGALLERY_ERROR_SAVING_COMMENT')); + + return false; + } + + if(isset($messenger)) + { + $messenger->send($message); + } + + $this->_mainframe->triggerEvent('onJoomAfterComment', array($row)); + + // After successfully storing the comment remove the comment text from the session, but keep the name + $this->_mainframe->setUserState('joom.comments.text', null); + + if($approved) + { + return 1; + } + else + { + return 2; + } + } + + /** + * Method to delete a comment + * + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + public function remove() + { + if(!$this->_user->authorise('core.manage', _JOOM_OPTION)) + { + JError::raiseError(500, JText::_('COM_JOOMGALLERY_COMMON_PERMISSION_DENIED')); + } + + $cmtid = JRequest::getInt('cmtid'); + + $query = $this->_db->getQuery(true) + ->delete(_JOOM_TABLE_COMMENTS) + ->where('cmtid = '.$cmtid) + ->where('cmtpic = '.$this->_id); + $this->_db->setQuery($query); + if(!$this->_db->query()) + { + $this->setError(JText::_('COM_JOOMGALLERY_ERROR_DELETING_COMMENT')); + + return false; + } + + return true; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/models/detail.php b/deployed/joomgallery/components/com_joomgallery/models/detail.php new file mode 100644 index 00000000..bb07e59a --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/models/detail.php @@ -0,0 +1,1280 @@ +setId((int)$id); + } + + /** + * Method to set the image identifier + * + * @param int $id Image ID number + * @return void + * @since 1.5.5 + */ + public function setId($id) + { + // Set new image ID if valid and wipe data + if(!$id) + { + $this->_mainframe->redirect(JRoute::_('index.php?view=gallery', false), JText::_('COM_JOOMGALLERY_COMMON_NO_IMAGE_SPECIFIED'), 'notice'); + } + $this->_id = $id; + $this->_image = null; + } + + /** + * Method to get the identifier + * + * @return int The image ID + * @since 1.5.5 + */ + public function getId() + { + return $this->_id; + } + + /** + * Method to get the image data + * + * @return object Image data object + * @since 1.5.5 + */ + public function getImage() + { + jimport('joomla.filesystem.file'); + + if(empty($this->_image)) + { + if($this->_loadImages()) + { + $images = $this->_images; + } + else + { + JError::raiseError(500, JText::_('Unable to load images')); + } + + #$image = $images[$this->_id]; see _loadImages() + foreach($images as $key => $row) + { + if($row->id == $this->_id) + { + $images[$key]->position = $key; + $image = $row; + break; + } + } + + if(!isset($image)) + { + $this->_mainframe->redirect(JRoute::_('index.php?view=gallery', false), JText::sprintf('Unable to load image with ID %d', $this->_id), 'error'); + } + + // Check whether the requested image is in a category + // which the current user is allowed to see it + $categories = $this->_ambit->getCategoryStructure(); + if(!isset($categories[$image->catid])) + { + JError::raiseError(500, JText::sprintf('Unable to load image with ID %d', $this->_id), 'error'); + } + + // Source url + $image->img_src = $this->_ambit->getImg('img_url', $image); + + // Information about original image if available + $orig = $this->_ambit->getImg('orig_path', $image); + if(JFile::exists($orig)) + { + $image->orig_exists = true; + $orig_info = getimagesize($orig); + $orig_size = filesize($orig); + $image->orig_size = number_format($orig_size / 1024, + 2, + JText::_('COM_JOOMGALLERY_COMMON_DECIMAL_SEPARATOR'), + JText::_('COM_JOOMGALLERY_COMMON_THOUSANDS_SEPARATOR') + ); + } + else + { + $image->orig_exists = false; + $orig_info[0] = 0; + $orig_info[1] = 0; + $image->orig_size = JText::_('COM_JOOMGALLERY_DETAIL_INFO_FILESIZE_ORIGINAL_NOT_AVAILABLE'); + } + + // Information about detail image + $img = $this->_ambit->getImg('img_path', $image); + $img_info = getimagesize($img); + $img_size = filesize($img); + + $image->img_size = number_format($img_size / 1024, + 2, + JText::_('COM_JOOMGALLERY_COMMON_DECIMAL_SEPARATOR'), + JText::_('COM_JOOMGALLERY_COMMON_THOUSANDS_SEPARATOR') + ); + + $image->orig_width = $orig_info[0]; + $image->orig_height = $orig_info[1]; + $image->img_width = $img_info[0]; + $image->img_height = $img_info[1]; + + $image->bigger_orig = false; + if( $image->orig_exists + && $image->orig_width > $image->img_width + && $image->orig_height > $image->img_height + ) + { + $image->bigger_orig = true; + } + + if($this->_config->get('jg_resizetomaxwidth')) + { + $ratio = max($image->img_width, $image->img_height); + $ratio = ($ratio / $this->_config->get('jg_maxwidth')); + $ratio = max($ratio, 1.0); + $image->width = (int)($image->img_width / $ratio); + $image->height = (int)($image->img_height / $ratio); + } + else + { + $image->width = $image->img_width; + $image->height = $image->img_height; + } + + if($image->imgauthor) + { + $image->author = $image->imgauthor; + } + else + { + if($this->_config->get('jg_showowner')) + { + $image->author = JHTML::_('joomgallery.displayname', $image->imgowner, 'detail'); + } + else + { + $image->author = JText::_('COM_JOOMGALLERY_COMMON_NO_DATA'); + } + } + + if( (($this->_config->get('jg_bigpic') == 1 && $this->_user->get('id')) + || ($this->_config->get('jg_bigpic_unreg') == 1 && !$this->_user->get('id')) + ) + #&& !$this->slideshow + && $image->bigger_orig + ) + { + $image->link = JHTML::_('joomgallery.openimage', $this->_config->get('jg_bigpic_open'), $image); + } + else + { + $image->link = ''; + } + + $this->_image = $image; + } + + return $this->_image; + } + + /** + * Method to get all the images of the current image's category + * The image has to be loaded first, because we need the catid + * + * @return array The images data array + * @since 1.5.5 + */ + public function getImages() + { + if($this->_loadImages()) + { + if($this->getImage()) + { + if(!in_array($this->_image->access, $this->_user->getAuthorisedViewLevels())) + { + $this->_mainframe->redirect(JRoute::_('index.php?view=gallery', false), + JText::_('COM_JOOMGALLERY_COMMON_MSG_NOT_ALLOWED_VIEW_IMAGE'), 'notice'); + } + } + else + { + $this->_mainframe->redirect(JRoute::_('index.php?view=gallery', false),JText::sprintf('Unable to load image with ID %d', $this->_id), 'error'); + } + + return $this->_images; + } + + return false; + } + + /** + * Method to get all the nametags of the current image + * + * @return array Nametags data array + * @since 1.5.5 + */ + public function getNametags() + { + if($this->_loadNametags()) + { + return $this->_nametags; + } + + return array(); + } + + /** + * Method to get all the comments of the current image + * + * @return array Comments data array + * @since 1.5.5 + */ + public function getComments() + { + if($this->_loadComments()) + { + return $this->_comments; + } + + return array(); + } + + /** + * Method to get the Exif data (HTML ouput) of the current image + * + * @return array Exif data array + * @since 1.5.5 + */ + public function getExifdata() + { + if($this->_loadExifdata()) + { + return $this->_exifdata; + } + + return false; + } + + /** + * Method to get the map data of the current image + * + * @return array Map data array + * @since 1.5.5 + */ + public function getMapdata() + { + if($this->_loadExifdata()) + { + if($this->_mapdata) + { + return $this->_mapdata; + } + } + + return false; + } + + /** + * Method to get the IPTC data (HTML ouput) of the current image + * + * @return array Iptc data data array + * @since 1.5.5 + */ + public function getIptcdata() + { + if($this->_loadIptcdata()) + { + return $this->_iptcdata; + } + + return false; + } + + /** + * Method to increment the hit counter for the image + * + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + public function hit() + { + if($this->_id) + { + $image = $this->getTable('joomgalleryimages'); + $image->hit($this->_id); + return true; + } + + return false; + } + + /** + * Tests if image is checked out + * + * @param int $uid A user id + * @return boolean True if it is checked out, false otherwise + * @since 1.5.5 + */ + public function isCheckedOut($uid = 0) + { + if($this->_loadImage()) + { + if($uid) + { + return ($this->_image->checked_out && $this->_image->checked_out != $uid); + } + else + { + return $this->_image->checked_out; + } + } + else + { + if(!$this->_id) + { + return false; + } + else + { + JError::raiseWarning( 0, 'Unable to Load Data'); + return false; + } + } + } + + /** + * Method to checkin/unlock the image + * + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + public function checkin() + { + if($this->_id) + { + $image = JTable::getInstance('joomgalleryimages'); + return $image->checkin($this->_id); + } + + return false; + } + + /** + * Method to checkout/lock the image + * + * @param int $uid User ID of the user checking the article out + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + public function checkout($uid = null) + { + if($this->_id) + { + // Make sure we have a user id to checkout the image with + if(is_null($uid)) + { + $user = JFactory::getUser(); + $uid = $user->get('id'); + } + // Let's get to it and checkout the thing... + $image = JTable::getInstance('joomgalleryimages'); + return $image->checkout($uid, $this->_id); + } + + return false; + } + + /** + * Method to load the images data + * + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + protected function _loadImages() + { + if(!$this->_id) + { + return false; + } + + // Load the images data if it doesn't already exist + if(empty($this->_images)) + { + $authorisedViewLevels = implode(',', $this->_user->getAuthorisedViewLevels()); + + // First get the category the image belongs too + $query = $this->_db->getQuery(true) + ->select('catid') + ->from(_JOOM_TABLE_IMAGES) + ->where('id = '.$this->_id); + + $this->_db->setQuery($query); + if(!($catid = $this->_db->loadResult())) + { + $this->_mainframe->redirect(JRoute::_('index.php?view=gallery', false), JText::sprintf('COM_JOOMGALLERY_COMMON_ERROR_IMAGE_NOT_FOUND', $this->_id), 'error'); + } + + // Get all the images data of that category + $query->clear() + ->select('a.*, a.owner AS imgowner, c.metadesc AS catmetadesc, c.metakey AS catmetakey') + ->select(JoomHelper::getSQLRatingClause('a').' AS rating') + ->from(_JOOM_TABLE_IMAGES.' AS a') + ->leftJoin(_JOOM_TABLE_CATEGORIES.' AS c ON c.cid = a.catid') + ->where('a.catid = '.$catid) + ->where('a.published = 1') + ->where('a.approved = 1') + ->where('(a.hidden = 0 OR a.id = '.$this->_id.')') + ->where('a.access IN ('.$authorisedViewLevels.')') + ->where('c.access IN ('.$authorisedViewLevels.')') + ->order('a.'.$this->_config->get('jg_firstorder')); + if($this->_config->get('jg_secondorder')) + { + $query->order('a.'.$this->_config->get('jg_secondorder')); + + if($this->_config->get('jg_thirdorder')) + { + $query->order('a.'.$this->_config->get('jg_thirdorder')); + } + } + + $this->_db->setQuery($query); + if(!$rows = $this->_db->loadObjectList()) + { + $this->_mainframe->redirect(JRoute::_('index.php?view=gallery', false), JText::sprintf('COM_JOOMGALLERY_COMMON_ERROR_IMAGE_NOT_FOUND', $this->_id), 'error'); + } + + $this->_images = $rows; + + return true; + } + + return true; + } + + /** + * Method to load the nametags data + * + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + protected function _loadNametags() + { + if(!$this->_id) + { + return false; + } + + // Load the nametags data if it doesn't already exist + if(empty($this->_nametags)) + { + $query = $this->_db->getQuery(true) + ->select('*, 500 AS maxzindex') + ->from(_JOOM_TABLE_NAMESHIELDS) + ->where('npicid = '.$this->_id); + + $this->_db->setQuery($query); + if(!$rows = $this->_db->loadObjectList()) + { + return false; + } + + $this->_nametags = $rows; + } + + return true; + } + + /** + * Method to load comments data + * + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + protected function _loadComments() + { + if(!$this->_id) + { + return false; + } + + // Load the comments data if it doesn't already exist + if(empty($this->_comments)) + { + $orderby = 'ASC'; + if($this->_config->get('jg_showcommentsarea') == 1) + { + $orderby = 'DESC'; + } + + $query = $this->_db->getQuery(true) + ->select('*') + ->from(_JOOM_TABLE_COMMENTS) + ->where('cmtpic = '.$this->_id) + ->where('published = 1') + ->where('approved = 1') + ->order('cmtid '.$orderby); + + $this->_db->setQuery($query); + if(!$rows = $this->_db->loadObjectList()) + { + return false; + } + + $this->_comments = $rows; + } + + return true; + } + + /** + * Method to load Exif data + * + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + protected function _loadExifdata() + { + if(!$this->_id) + { + return false; + } + + // Load the Exif data if it doesn't already exist + if(empty($this->_exifdata) && $this->_exifdata !== false) + { + if(empty($this->image)) + { + if(!$this->getImage()) + { + return false; + } + } + + $mapdata = false; + + // PHP's exif only accepts JPEGs or TIFFs + $valid_extensions = array('jpg', 'jpeg', 'jpe'); + $fileextension = strtolower(JFile::getExt($this->_image->imgfilename)); + $exif_array = array(); + if(in_array($fileextension, $valid_extensions)) + { + $exif_array = @exif_read_data($this->_ambit->getImg('orig_path', $this->_image), 'EXIF, IFD0, GPS', true); + if(!$exif_array) + { + return false; + } + } + else + { + return false; + } + + $language = JFactory::getLanguage(); + $language->load('com_joomgallery.exif'); + + require_once(JPATH_COMPONENT_ADMINISTRATOR.'/includes/exifarray.php'); + + $ii = 0; + + $ifdotags = explode(',', $this->_config->get('jg_ifdotags')); + $subifdtags = explode(',', $this->_config->get('jg_subifdtags')); + $gpstags = explode(',', $this->_config->get('jg_gpstags')); + + // For GPS tags check for enabled geotagging + if($this->_config->get('jg_showgeotagging')) + { + $gpstags = array_unique(array_merge($gpstags, array(1, 2, 3, 4, 5))); + sort($gpstags); + } + + $countifdotags = count($ifdotags); + $countsubifdtags = count($subifdtags); + $countgpstags = count($gpstags); + + $definitions = array( + 1 => array ('TAG' => 'IFD0', 'FORS' => $ifdotags, 'FOR' => '$ifdotag'), + 2 => array ('TAG' => 'EXIF', 'FORS' => $subifdtags, 'FOR' => '$subifdtag'), + 3 => array ('TAG' => 'GPS', 'FORS' => $gpstags, 'FOR' => '$gpstags') + ); + $count = count($definitions); + $output = ''; + + for($ii = 1; $ii <= $count; $ii++) + { + $tagcat = $definitions[$ii]['TAG']; + $jgtags = $definitions[$ii]['FORS']; + $jgtag = $definitions[$ii]['FOR']; + + $k = 0; + foreach($jgtags as $jgtag) + { + if(!empty($jgtag) && isset($exif_array[$tagcat][$exif_config_array[$tagcat][$jgtag]['Attribute']])) + { + // Disable output of GPS tags if they aren't selected for displaying + // (the information has to be collected if geotagging is enabled, so they are also in the array) + if($tagcat != 'GPS' || strpos($this->_config->get('jg_gpstags').',', $jgtag.',') !== false) + { + $kk = $k % 2 + 1; + $tagdata = $exif_array[$tagcat][$exif_config_array[$tagcat][$jgtag]['Attribute']]; + $output .= "
    \n"; + $output .= "
    \n"; +// $output .= " ".$jgtag."\n"; +// $output .= "  \n"; + $output .= " ".$exif_config_array[$tagcat][$jgtag]['Name']."\n"; + $output .= "
    \n"; + $output .= "
    \n"; + } + if($exif_config_array[$tagcat][$jgtag]['Calculation'] =='Denum') + { + list($numerator, $denumerator) = explode('/', $tagdata); + $tagdata = ($numerator / $denumerator); + $tagdata = round($tagdata,2); + if($exif_config_array[$tagcat][$jgtag]['Attribute'] == 'FNumber') + { + $tagdata = JText::_('COM_JOOMGALLERY_SUBIFD_FNUMBER_F').$tagdata; + } + } + if($exif_config_array[$tagcat][$jgtag]['Calculation'] == 'Array') + { + $tagdata = $exif_config_array[$tagcat][$jgtag][$exif_array[$tagcat][$exif_config_array[$tagcat][$jgtag]['Attribute']]]; + } + if($exif_config_array[$tagcat][$jgtag]['Attribute'] == 'ImageDescription' + || $exif_config_array[$tagcat][$jgtag]['Attribute'] == 'Artist' + || $exif_config_array[$tagcat][$jgtag]['Attribute'] == 'Copyright') + { + $tagdata = $exif_array[$tagcat][$exif_config_array[$tagcat][$jgtag]['Attribute']]; + $from_charset = 'ASCII'; + $to_charset = 'UTF-8'; + if(function_exists('iconv')) + { + $fixedenteties = htmlentities($tagdata); + $fixedcharset = iconv($from_charset, $to_charset, $fixedenteties); + } + else + { + $fixedcharset = $tagdata; + } + if(!$this->isUtf8($fixedcharset)) + { + $tagdata = htmlspecialchars_decode($this->utf8EncodeMix($fixedcharset, false)); + } + else + { + $tagdata = htmlspecialchars_decode($fixedcharset); + } + } + if( $exif_config_array[$tagcat][$jgtag]['Attribute'] == 'ReferenceBlackWhite' + || $exif_config_array[$tagcat][$jgtag]['Attribute'] == 'PrimaryChromaticities' + || $exif_config_array[$tagcat][$jgtag]['Attribute'] == 'WhitePoint' + || $exif_config_array[$tagcat][$jgtag]['Attribute'] == 'YCbCrCoefficients' + ) + { + if($exif_config_array[$tagcat][$jgtag]['Attribute'] == 'WhitePoint') + { + $arraynum = 2; + $counter = 1; + } + elseif($exif_config_array[$tagcat][$jgtag]['Attribute'] == 'YCbCrCoefficients') + { + $arraynum = 3; + $counter = 2; + } + else + { + $arraynum = 6; + $counter = 5; + } + $tagdata = '['; + for($num = 0; $num < $arraynum; $num++) + { + $data = $exif_array[$tagcat][$exif_config_array[$tagcat][$jgtag]['Attribute']][$num]; + list($numerator, $denumerator) = explode('/', $data); + $data = ($numerator / $denumerator); + $tagdata .= $data; + if($num < $counter) + { + $tagdata .= ', '; + } + } + $tagdata .= ']'; + } + if($exif_config_array[$tagcat][$jgtag]['Attribute'] == 'ExifVersion') + { + if($exif_array[$tagcat][$exif_config_array[$tagcat][$jgtag]['Attribute']] == '0220') + { + $tagdata = JText::_('COM_JOOMGALLERY_SUBIFD_EXIFVERSION_VERSION') . ' 2.2'; + } + elseif($exif_array[$tagcat][$exif_config_array[$tagcat][$jgtag]['Attribute']] == '0210') + { + $tagdata = JText::_('COM_JOOMGALLERY_SUBIFD_EXIFVERSION_VERSION') . ' 2.1'; + } + } + if($exif_config_array[$tagcat][$jgtag]['Attribute'] == 'ComponentsConfiguration') + { + $tagdata = ''; + for($num = 0; $num < 4; $num++ ) + { + $value = ord($exif_array[$tagcat][$exif_config_array[$tagcat][$jgtag]['Attribute']]{$num}); + $tagdata .= JText::_('COM_JOOMGALLERY_SUBIFD_COMPONENTSCONFIGURATION_COMPONENT') . ( $num + 1 ) . ': '; + switch($value) + { + case 0: + $tagdata .= JText::_('COM_JOOMGALLERY_SUBIFD_COMPONENTSCONFIGURATION_0'); + break; + case 1: + $tagdata .= JText::_('COM_JOOMGALLERY_SUBIFD_COMPONENTSCONFIGURATION_1'); + break; + case 2: + $tagdata .= JText::_('COM_JOOMGALLERY_SUBIFD_COMPONENTSCONFIGURATION_2'); + break; + case 3: + $tagdata .= JText::_('COM_JOOMGALLERY_SUBIFD_COMPONENTSCONFIGURATION_3'); + break; + case 4: + $tagdata .= JText::_('COM_JOOMGALLERY_SUBIFD_COMPONENTSCONFIGURATION_4'); + break; + case 5: + $tagdata .= JText::_('COM_JOOMGALLERY_SUBIFD_COMPONENTSCONFIGURATION_5'); + break; + case 6: + $tagdata .= JText::_('COM_JOOMGALLERY_SUBIFD_COMPONENTSCONFIGURATION_6'); + break; + default: + $tagdata .= JText::_('COM_JOOMGALLERY_SUBIFD_COMPONENTSCONFIGURATION_UNKNOWN') . $value; + } + $tagdata .= '
    '; + } + } + if($exif_config_array[$tagcat][$jgtag]['Attribute'] == 'FileSource') + { + $tagdata = ''; + $value = ord($exif_array[$tagcat][$exif_config_array[$tagcat][$jgtag]['Attribute']]{0}); + switch($value) + { + case 3: + $tagdata .= JText::_('COM_JOOMGALLERY_SUBIFD_FILESOURCE_3'); + break; + default: + $tagdata = JText::_('COM_JOOMGALLERY_SUBIFD_FILESOURCE_UNKNOWN') . $value; + } + } + if($exif_config_array[$tagcat][$jgtag]['Attribute'] == 'SceneType') + { + $tagdata = ''; + $value = ord($exif_array[$tagcat][$exif_config_array[$tagcat][$jgtag]['Attribute']]{0}); + switch($value) + { + case 1: + $tagdata .= JText::_('COM_JOOMGALLERY_SUBIFD_SCENETYPE_1'); + break; + default: + $tagdata = JText::_('COM_JOOMGALLERY_SUBIFD_SCENETYPE_UNKNOWN') . $value; + } + } + if($exif_config_array[$tagcat][$jgtag]['Attribute'] == 'GPSLatitudeRef') + { + $tagdata = ''; + $value = $exif_array[$tagcat][$exif_config_array[$tagcat][$jgtag]['Attribute']]; + switch($value) + { + case 'N': + $tagdata .= JText::_('COM_JOOMGALLERY_GPS_GPSLATITUDEREF_N'); + break; + case 'S': + $tagdata .= JText::_('COM_JOOMGALLERY_GPS_GPSLATITUDEREF_S'); + break; + } + + // Geotagging + if($this->_config->get('jg_showgeotagging')) + { + $map_direction = $value; + } + } + if($exif_config_array[$tagcat][$jgtag]['Calculation'] == 'DegMinSec') + { + $tagdata = ''; + $degree = $exif_array[$tagcat][$exif_config_array[$tagcat][$jgtag]['Attribute']][0]; + list($numerator, $denumerator) = explode('/', $degree); + $degree = ($numerator/$denumerator); + $tagdata .= $degree.'°'; + $tagdata .= '  '; + $minutes = $exif_array[$tagcat][$exif_config_array[$tagcat][$jgtag]['Attribute']][1]; + list($numerator, $denumerator) = explode('/', $minutes); + $minutes = ($numerator/$denumerator); + $tagdata .= $minutes."'"; + $tagdata .= "  "; + $seconds = $exif_array[$tagcat][$exif_config_array[$tagcat][$jgtag]['Attribute']][2]; + list($numerator, $denumerator) = explode('/', $seconds); + $seconds = ($numerator / $denumerator); + $tagdata .= $seconds."''"; + + // Geotagging + if($this->_config->get('jg_showgeotagging')) + { + $mapdata[$map_direction] = $degree + ( $minutes / 60 ) + ( $seconds / 3600 ); + } + } + if($exif_config_array[$tagcat][$jgtag]['Attribute'] == 'GPSLongitudeRef') + { + $tagdata = ''; + $value = $exif_array[$tagcat][$exif_config_array[$tagcat][$jgtag]['Attribute']]; + switch($value) + { + case 'E': + $tagdata .= JText::_('COM_JOOMGALLERY_GPS_GPSLONGITUDEREF_E'); + break; + case 'W': + $tagdata .= JText::_('COM_JOOMGALLERY_GPS_GPSLONGITUDEREF_W'); + break; + } + + // Geotagging + if($this->_config->get('jg_showgeotagging')) + { + $map_direction = $value; + } + } + if($exif_config_array[$tagcat][$jgtag]['Attribute'] == 'GPSAltitudeRef') + { + $tagdata = ''; + $value = $exif_array[$tagcat][$exif_config_array[$tagcat][$jgtag]['Attribute']]{0}; + $value = bindec($value); + switch($value) + { + case '0': + $tagdata .= JText::_('COM_JOOMGALLERY_GPS_GPSALTITUDEREF_0'); + break; + case '1': + $tagdata .= JText::_('COM_JOOMGALLERY_GPS_GPSALTITUDEREF_1'); + break; + } + } + + // Disable output of GPS tags if they aren't selected for displaying + // (the information has to be collected if geotagging is enabled, so they are also in the array) + if($tagcat == 'GPS' && strpos($this->_config->get('jg_gpstags').',', $jgtag.',') === false) + { + continue; + } + + if($tagdata == '') + { + $tagdata = ' '; + } + + $tagdata = str_replace('Â', '', $tagdata); + + $output .= ' '.$tagdata; + + if($exif_config_array[$tagcat][$jgtag]['Units'] != '') + { + $output .= ' '; + $output .= $exif_config_array[$tagcat][$jgtag]['Units']."\n"; + } + else + { + $output .= " \n"; + } + $output .= "
    \n"; + $output .= "
    \n"; + $k++; + } + // else + // { + // $kk = $k%2+1; + // $output .= "
    \n"; + // $output .= "
    \n"; + // $output .= " ".$jgtag."\n"; + // $output .= "  \n"; + // $output .= " ".$exif_config_array[$tagcat][$jgtag]['Name']."\n"; + // $output .= "
    \n"; + // $output .= "
    \n"; + // $output .= " nicht definiert"; + // $output .= "
    \n"; + // $output .= "
    \n"; + // $k++; + // } + } + } + + if($output) + { + $this->_exifdata = $output; + } + else + { + $this->_exifdata = false; + } + + $this->_mapdata = $mapdata; + + return true; + } + + return true; + } + + /** + * Method to load iptc data + * + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + protected function _loadIptcdata() + { + if(!$this->_id) + { + return false; + } + + // Load the iptc data if it doesn't already exist + if(empty($this->_iptcdata)) + { + if(empty($this->_image)) + { + if(!$this->getImage()) + { + return false; + } + } + + $valid_extensions = array('jpg', 'jpeg', 'jpe'); + $fileextension = strtolower(JFile::getExt($this->_image->imgfilename)); + $iptc_array = array(); + if(in_array($fileextension, $valid_extensions)) + { + $iptcimage = getimagesize($this->_ambit->getImg('orig_path', $this->_image), $info); + if(isset($info['APP13'])) + { + $iptc_array = iptcparse($info['APP13']); + } + if(!$iptc_array) + { + return false; + } + } + else + { + return false; + } + + $language = JFactory::getLanguage(); + $language->load('com_joomgallery.iptc'); + + require_once(JPATH_COMPONENT_ADMINISTRATOR.'/includes/iptcarray.php'); + + $ii = 0; + + $iptctags = explode(',', $this->_config->get('jg_iptctags')); + + $charsets = array( + 'macintosh', + 'ASCII', + 'ISO-8859-1', + 'UCS-4', + 'UCS-4BE', + 'UCS-4LE', + 'UCS-2', + 'UCS-2BE', + 'UCS-2LE', + 'UTF-32', + 'UTF-32BE', + 'UTF-32LE', + 'UTF-16', + 'UTF-16BE', + 'UTF-16LE', + 'UTF-7', + 'UTF7-IMAP', + 'UTF-8', + 'EUC-JP', + 'SJIS', + 'eucJP-win', + 'SJIS-win', + 'ISO-2022-JP', + 'JIS', + 'ISO-8859-2', + 'ISO-8859-3', + 'ISO-8859-4', + 'ISO-8859-5', + 'ISO-8859-6', + 'ISO-8859-7', + 'ISO-8859-8', + 'ISO-8859-9', + 'ISO-8859-10', + 'ISO-8859-13', + 'ISO-8859-14', + 'ISO-8859-15', + 'byte2be', + 'byte2le', + 'byte4be', + 'byte4le', + 'BASE64', + '7bit', + '8bit', + 'EUC-CN', + 'CP936', + 'HZ', + 'EUC-TW', + 'CP950', + 'BIG-5', + 'EUC-KR', + 'UHC', + 'ISO-2022-KR', + 'Windows-1251', + 'Windows-1252', + 'CP866', + 'KOI8-R' + ); + + if((isset($iptc_array['1#090'][0])) && in_array($iptc_array['1#090'][0], $charsets)) + { + $from_charset = $iptc_array['1#090'][0]; + } + else + { + $from_charset = ''; + } + + $to_charset = 'UTF-8'; + + $k = 0; + $output = ''; + foreach($iptctags as $iptctag) + { + if(!empty($iptctag) && isset($iptc_config_array['IPTC'][$iptctag]['IMM'])) + { + $realiptctag = str_replace(':', '#', $iptc_config_array['IPTC'][$iptctag]['IMM']); + if(isset($iptc_array[$realiptctag])) + { + if($realiptctag != '2#025') + { + $kk = $k%2+1; + $output .= "
    \n"; + $output .= "
    \n"; + $output .= " ".$iptc_config_array['IPTC'][$iptctag]['Name']."\n"; + $output .= "
    \n"; + $output .= "
    \n"; + if(function_exists('iconv')) + { + $fixedenteties = htmlentities($iptc_array[$realiptctag][0]); + $fixedcharset = iconv($from_charset, $to_charset, $fixedenteties); + } + else + { + $fixedcharset = $iptc_array[$realiptctag][0]; + } + if(!$this->isUtf8($fixedcharset)) + { + $tagdata = htmlspecialchars_decode($this->utf8EncodeMix($fixedcharset, false)); + } + else + { + $tagdata = htmlspecialchars_decode($fixedcharset); + } + if($tagdata == '') + { + $tagdata = ' '; + } + $output .= " ".$tagdata.""; + $output .= "
    \n"; + $output .= "
    \n"; + $k++; + } + else + { + $num = count($iptc_array['2#025']); + if($num > 0) + { + $kk = $k % 2 + 1; + $tagdata = ''; + $output .= "
    \n"; + $output .= "
    \n"; + $output .= " ".$iptc_config_array['IPTC'][$iptctag]['Name']." \n"; + $output .= "
    \n"; + $output .= "
    \n"; + for($i = 0; $i < $num; $i++) + { + if(function_exists('iconv')) + { + $fixedenteties = htmlentities($iptc_array[$realiptctag][$i]); + $fixedcharset = iconv($from_charset, $to_charset, $fixedenteties); + } + else + { + $fixedcharset = $iptc_array[$realiptctag][$i]; + } + if(!$this->isUtf8($fixedcharset)) + { + $tagdata .= htmlspecialchars_decode(utf8_encode_mix($fixedcharset, false)); + } + else + { + $tagdata .= htmlspecialchars_decode($fixedcharset); + } + if($i < $num-1) + { + $tagdata .= ', '; + } + } + if(empty($tagdata)) + { + $tagdata = ' '; + } + $output .= ' '.$tagdata; + $output .= "
    \n"; + $output .= "
    \n"; + } + } + } + } + } + + $this->_iptcdata = $output; + + return true; + } + + return true; + } + + /** + * Returns true if $string is valid UTF-8 and false otherwise. + * + * From http://w3.org/International/questions/qa-forms-utf-8.html + * + * @param string $string The string to be checked + * @return boolean True if $string is valid UTF-8, false otherwise + * @since 1.0.0 + */ + public function isUtf8($string) + { + return preg_match('%^(?: + [\x09\x0A\x0D\x20-\x7E] # ASCII + | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte + | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs + | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte + | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates + | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 + | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 + | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 + )*$%xs', $string); + + } + + /** + * Encodes an ISO-8859-1 string to UTF-8 + * + * Recursive call + * + * @param string/array $input The string(s) to be modified + * @param boolean $encode_keys True if the array keys should be encoded, too + * @return string/array The encoded string(s) + * @since 1.0.0 + */ + public function utf8EncodeMix($input, $encode_keys = false) + { + if(is_array($input)) + { + $result = array(); + foreach($input as $k => $v) + { + $key = ($encode_keys) ? utf8_encode($k) : $k; + $result[$key] = $this->utf8EncodeMix($v, $encode_keys); + } + } + else + { + $result = utf8_encode($input); + } + + return $result; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/models/edit.php b/deployed/joomgallery/components/com_joomgallery/models/edit.php new file mode 100644 index 00000000..7bf80c97 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/models/edit.php @@ -0,0 +1,878 @@ +_user->get('id') && !$this->_config->get('jg_unregistered_permissions')) + { + throw new Exception(JText::_('COM_JOOMGALLERY_COMMON_MSG_YOU_ARE_NOT_LOGGED')); + } + } + + /** + * Method to set the image identifier + * + * @param int $id The image ID + * @return void + * @since 1.5.5 + */ + public function setId($id) + { + // Set new image ID if valid and wipe data + if(!$id) + { + $this->_mainframe->redirect(JRoute::_('index.php?view=userpanel', false), JText::_('COM_JOOMGALLERY_COMMON_NO_IMAGE_SPECIFIED'), 'notice'); + } + + $this->_id = $id; + $this->_image = null; + } + + /** + * Method to get the image data + * + * @return object Image data object + * @since 1.5.5 + */ + public function getImage() + { + if($this->_loadImage()) + { + // Check whether we are allowed to edit the image + $asset = _JOOM_OPTION.'.image.'.$this->_id; + if(!$this->_user->authorise('core.edit', $asset) && (!$this->_user->authorise('core.edit.own', $asset) || !$this->_image->owner || $this->_image->owner != $this->_user->get('id'))) + { + $this->_mainframe->redirect(JRoute::_('index.php?option=com_joomgallery&view=gallery', false), JText::_('COM_JOOMGALLERY_COMMON_MSG_NOT_ALLOWED_TO_EDIT_IMAGE'), 'notice'); + } + + return $this->_image; + } + + return false; + } + + /** + * Method to check whether the image can have its state edited by the current user + * + * @param array Holds the data of the image + * @return boolean True if the current user is allowed to change the state of the image, false otherwise + * @since 2.0 + */ + protected function canEditState($data) + { + // Check for existing image + if(isset($data['id']) && $data['id']) + { + return $this->_user->authorise('core.edit.state', _JOOM_OPTION.'.image.'.(int) $data['id']); + } + else + { + // Maybe it is a new image, so check against the category + if(isset($data['catid']) && $data['catid']) + { + return $this->_user->authorise('core.edit.state', _JOOM_OPTION.'.category.'.(int) $data['catid']); + } + else + { + // Default to component settings if neither image nor category known + return $this->_user->authorise('core.edit.state', _JOOM_OPTION); + } + } + } + + /** + * Method to get the form for the image + * + * @param array Holds the data of the image (if available) + * @return mixed A JForm object on success, false on failure + * @since 2.0 + */ + public function getForm($data = array(), $formName = 'edit') + { + JForm::addFormPath(JPATH_COMPONENT.'/models/forms'); + JForm::addFieldPath(JPATH_COMPONENT_ADMINISTRATOR.'/models/fields'); + JForm::addRulePath(JPATH_COMPONENT_ADMINISTRATOR.'/models/rules'); + + $form = JForm::getInstance(_JOOM_OPTION.'.'.$formName, $formName); + if(empty($form)) + { + return false; + } + + if(empty($data)) + { + $data = (array) $this->getImage(); + } + + // Allow plugins to preprocess the form + JPluginHelper::importPlugin('joomgallery'); + $this->preprocessForm($form, $data); + + if(!$this->canEditState($data)) + { + // Disable fields for display + $form->setFieldAttribute('published', 'disabled', 'true'); + + // Unset the data of fields which we aren't allowed to change + $form->setFieldAttribute('published', 'filter', 'unset'); + } + + if(!$this->_config->get('jg_edit_metadata')) + { + $form->setFieldAttribute('metakey', 'disabled', 'true'); + $form->setFieldAttribute('metakey', 'filter', 'unset'); + $form->setFieldAttribute('metadesc', 'disabled', 'true'); + $form->setFieldAttribute('metadesc', 'filter', 'unset'); + } + + return $form; + } + + /** + * Method to allow plugins to preprocess the form + * + * @param JForm $form A JForm object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import (defaults to "content"). + * @return void + * @since 2.1 + */ + protected function preprocessForm(JForm $form, $data, $group = 'content') + { + // Import the appropriate plugin group + JPluginHelper::importPlugin($group); + + // Get the dispatcher + $dispatcher = JDispatcher::getInstance(); + + // Trigger the form preparation event + $results = $dispatcher->trigger('onContentPrepareForm', array($form, $data)); + + // Check for errors encountered while preparing the form + if(count($results) && in_array(false, $results, true)) + { + // Get the last error + $error = $dispatcher->getError(); + + if(!($error instanceof Exception)) + { + throw new Exception($error); + } + } + } + + /** + * Method to load the image data + * + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + protected function _loadImage() + { + if(empty($this->_image)) + { + $row = $this->getTable('joomgalleryimages'); + + if(!$row->load($this->_id)) + { + $row->imgtitle = $this->_mainframe->getUserStateFromRequest('joom.image.imgtitle', 'imgtitle'); + $row->imgtext = $this->_mainframe->getUserStateFromRequest('joom.image.imgtext', 'imgtext'); + $row->imgauthor = $this->_mainframe->getUserStateFromRequest('joom.image.imgauthor', 'imgauthor'); + $row->owner = $this->_mainframe->getUserStateFromRequest('joom.image.owner', 'owner'); + $row->published = $this->_mainframe->getUserStateFromRequest('joom.image.published', 'published', 1, 'int'); + $row->imgfilename = $this->_mainframe->getUserStateFromRequest('joom.image.imgfilename', 'imgfilename'); + $row->imgthumbname = $this->_mainframe->getUserStateFromRequest('joom.image.imgthumbname', 'imgthumbname'); + $row->catid = $this->_mainframe->getUserStateFromRequest('joom.image.catid', 'catid', 0, 'int'); + $row->thumb_url = null; + //Source category for original and detail picture + #$row->detail_catid = $this->_mainframe->getUserStateFromRequest('joom.image.detail_catid', 'detail_catid', 0, 'int'); + //Source category for thumbnail + #$row->thumb_catid = $this->_mainframe->getUserStateFromRequest('joom.image.thumb_catid', 'thumb_catid', 0, 'int'); + #$row->copy_original = $this->_mainframe->getUserStateFromRequest('joom.image.copy_original', 'copy_original', 0, 'int'); + } + else + { + $row->thumb_url = $this->_ambit->getImg('thumb_url', $row); + } + + JPluginHelper::importPlugin('joomgallery'); + $this->_mainframe->triggerEvent('onContentPrepareData', array(_JOOM_OPTION.'.image', $row)); + + $this->_image = $row; + } + + return true; + } + + /** + * Method to validate the form data + * + * @param object $form The form to validate against + * @param array $data The data to validate + * @return mixed Array of filtered data if valid, false otherwise + * @since 2.0 + */ + protected function _validate($form, $data) + { + // Filter and validate the form data + $data = $form->filter($data); + $return = $form->validate($data); + + // Check for an error + if(JError::isError($return)) + { + $this->setError($return->getMessage()); + return false; + } + + // Check the validation results + if ($return === false) + { + // Get the validation messages from the form + foreach($form->getErrors() as $message) + { + $this->setError(JText::_($message)); + } + return false; + } + + return $data; + } + + /** + * Method to store an edited image + * + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + public function store($data = null) + { + $row = $this->getTable('joomgalleryimages'); + + if(is_null($data)) + { + $data = JRequest::get('post', 2); + } + + // Check for validation errors + $form = $this->getForm($data); + $data = $this->_validate($form, $data); + if($data === false) + { + return false; + } + + // Check whether it is an existing image + if(!$id = intval($data['id'])) + { + $this->_mainframe->redirect(JRoute::_('index.php?view=gallery', false), JText::_('COM_JOOMGALLERY_COMMON_NO_IMAGE_SPECIFIED'), 'error'); + } + + // Load image data from the database + $row->load($id); + + // Check whether we are allowed to edit it + $asset = _JOOM_OPTION.'.image.'.$id; + if(!$this->_user->authorise('core.edit', $asset) && (!$this->_user->authorise('core.edit.own', $asset) || !$row->owner || $row->owner != $this->_user->get('id'))) + { + $this->_mainframe->redirect(JRoute::_('index.php?option=com_joomgallery&view=gallery', false), JText::_('COM_JOOMGALLERY_COMMON_MSG_NOT_ALLOWED_TO_EDIT_IMAGE'), 'notice'); + } + + // Read old category ID + $catid_old = $row->catid; + + // Bind the form fields to the images table + if(!$row->bind($data)) + { + $this->setError($row->getError()); + + return false; + } + + // Load category information for permission checks + $query = $this->_db->getQuery(true) + ->select('cid, owner') + ->from(_JOOM_TABLE_CATEGORIES) + ->where('cid = '.$row->catid); + $this->_db->setQuery($query); + $category = $this->_db->loadObject(); + + $move = false; + if(isset($catid_old) && $catid_old != $row->catid) + { + $move = true; + + // Check whether the new category is a valid one + if(!$category) + { + // If that's not the case store the image in the old category and leave a message + $move = false; + $row->catid = $catid_old; + + $this->_mainframe->enqueueMessage(JText::_('COM_JOOMGALLERY_COMMON_MSG_NO_VALID_CATEGORY_SELECTED'), 'notice'); + } + else + { + // Access check for the selected new category + if( !$this->_user->authorise('joom.upload', _JOOM_OPTION.'.category.'.$row->catid) + && + ( !$this->_user->authorise('joom.upload.inown', _JOOM_OPTION.'.category.'.$row->catid) + || !$category->owner + || $category->owner != $this->_user->get('id') + ) + ) + { + $move = false; + $row->catid = $catid_old; + + $this->_mainframe->enqueueMessage(JText::_('COM_JOOMGALLERY_COMMON_MSG_NOT_ALLOWED_STORE_IMAGE_IN_CATEGORY'), 'notice'); + } + } + } + + if($move && !$this->moveImage($row, $row->catid, $catid_old)) + { + $this->_mainframe->enqueueMessage(JText::_('COM_JOOMGALLERY_EDITIMAGE_MSG_COULD_NOT_MOVE_IMAGE'), 'notice'); + + return false; + } + else + { + // Make sure the record is valid + if(!$row->check()) + { + $this->setError($row->getError()); + + return false; + } + + // Store the entry to the database + if(!$row->store()) + { + $this->setError($row->getError()); + + return false; + } + } + + // Successfully stored image (and moved) + $row->reorder('catid = '.$row->catid); + if(isset($catid_old) && $catid_old != $row->catid) + { + $row->reorder('catid = '.$catid_old); + } + + $this->_mainframe->triggerEvent('onContentAfterSave', array(_JOOM_OPTION.'.image', &$row, false)); + + return $row->id; + } + + /** + * Method to store an edited image from the quick edit form + * + * @param int ID of the image to edit + * @param array Associative array of image data to store + * @return boolean True on success + * @since 3.3 + */ + public function quickEdit($id, $data) + { + $row = $this->getTable('joomgalleryimages'); + + // Check for validation errors + $form = $this->getForm($data, 'quickedit'); + $data = $this->_validate($form, $data); + if($data === false) + { + throw new RuntimeException($this->getError()); + } + + // Check whether it is an existing image + $id = (int) $id; + if(!$id) + { + throw new RuntimeException(JText::_('COM_JOOMGALLERY_COMMON_NO_IMAGE_SPECIFIED')); + } + + // Load image data from the database + $row->load($id); + + // Check whether we are allowed to edit it + $asset = _JOOM_OPTION.'.image.'.$id; + if(!$this->_user->authorise('core.edit', $asset) && (!$this->_user->authorise('core.edit.own', $asset) || !$row->owner || $row->owner != $this->_user->get('id'))) + { + throw new RuntimeException(JText::_('COM_JOOMGALLERY_COMMON_MSG_NOT_ALLOWED_TO_EDIT_IMAGE')); + } + + // Bind the form fields to the images table + if(!$row->bind($data)) + { + throw new RuntimeException($row->getError()); + } + + // Make sure the record is valid + if(!$row->check()) + { + throw new RuntimeException($row->getError()); + } + + // Store the entry to the database + if(!$row->store()) + { + throw new RuntimeException($row->getError()); + } + + // Successfully stored image + $this->_mainframe->triggerEvent('onContentAfterSave', array(_JOOM_OPTION.'.image.quick', &$row, false)); + + return true; + } + + /** + * Method to delete an image + * + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + public function delete() + { + jimport('joomla.filesystem.file'); + + $row = $this->getTable('joomgalleryimages'); + + $row->load($this->_id); + + // Check whether we are allowed to delete this image + if(!$this->_user->authorise('core.delete', _JOOM_OPTION.'.image.'.$row->id)) + { + throw new RuntimeException(JText::_('COM_JOOMGALLERY_IMAGE_MSG_DELETE_NOT_PERMITTED')); + } + + // Database query to check if there are other images which this + // thumbnail is assigned to and how many of them exist + $query = $this->_db->getQuery(true); + $query->select('COUNT(id)') + ->from(_JOOM_TABLE_IMAGES) + ->where('imgthumbname = \''.$row->imgthumbname.'\'') + ->where('id != '.$row->id) + ->where('catid = '.$row->catid); + $this->_db->setQuery($query); + $thumb_count = $this->_db->loadResult(); + + // Database query to check if there are other images which this + // detail image is assigned to and how many of them exist + $query->clear('where'); + $query->where('imgfilename = \''.$row->imgfilename.'\'') + ->where('id != '.$row->id) + ->where('catid = '.$row->catid); + $this->_db->setQuery($query); + $img_count = $this->_db->loadResult(); + + // Delete the thumbnail if there are no other images + // in same category assigned to it + if(!$thumb_count) + { + $thumb = $this->_ambit->getImg('thumb_path', $row); + if(!JFile::delete($thumb)) + { + // If thumbnail is not deletable set an error message + JLog::add(JText::sprintf('COM_JOOMGALLERY_EDITIMAGE_MSG_COULD_NOT_DELETE_THUMB', $thumb), JLog::WARNING, 'jerror'); + } + } + + // Delete the detail if there are no other detail and + // original images from same category assigned to it + if(!$img_count) + { + $img = $this->_ambit->getImg('img_path', $row); + if(!JFile::delete($img)) + { + // If detail is not deletable set an error message + JLog::add(JText::sprintf('COM_JOOMGALLERY_EDITIMAGE_MSG_COULD_NOT_DELETE_IMAGE', $img), JLog::WARNING, 'jerror'); + } + // Original exists? + $orig = $this->_ambit->getImg('orig_path', $row); + if(JFile::exists($orig)) + { + // Delete it + if(!JFile::delete($orig)) + { + // If original is not deletable set an error message + JLog::add(JText::sprintf('COM_JOOMGALLERY_EDITIMAGE_MSG_COULD_NOT_DELETE_ORIG', $orig), JLog::WARNING, 'jerror'); + } + } + } + + // Delete the corresponding database entries of the comments + $query->clear(); + $query->delete(_JOOM_TABLE_COMMENTS) + ->where('cmtpic = '.$this->_id); + $this->_db->setQuery($query); + if(!$this->_db->query()) + { + JLog::add(JText::sprintf('COM_JOOMGALLERY_EDITIMAGE_MSG_COULD_NOT_DELETE_COMMENTS', $this->_id), JLog::WARNING, 'jerror'); + } + + // Delete the corresponding database entries of the name tags + $query->clear(); + $query->delete(_JOOM_TABLE_NAMESHIELDS) + ->where('npicid = '.$this->_id); + $this->_db->setQuery($query); + if(!$this->_db->query()) + { + JLog::add(JText::sprintf('COM_JOOMGALLERY_EDITIMAGE_MSG_COULD_NOT_DELETE_NAMETAGS', $this->_id), JLog::WARNING, 'jerror'); + } + + // Delete the corresponding database entries of the Votes + $query->clear(); + $query->delete(_JOOM_TABLE_VOTES) + ->where('picid = '.$this->_id); + $this->_db->setQuery($query); + if(!$this->_db->query()) + { + JLog::add(JText::_('COM_JOOMGALLERY_EDITIMAGE_MSG_COULD_NOT_DELETE_VOTES'), JLog::WARNING, 'jerror'); + } + + // Delete the database entry of the image + if(!$row->delete()) + { + throw new RuntimeException(JText::sprintf('COM_JOOMGALLERY_EDITIMAGE_MSG_COULD_NOT_DELETE_IMAGE_DATA', $this->_id)); + } + + // Image successfully deleted + $row->reorder('catid = '.$row->catid); + + JPluginHelper::importPlugin('joomgallery'); + $this->_mainframe->triggerEvent('onContentAfterDelete', array(_JOOM_OPTION.'.image', $row)); + + return true; + } + + /** + * Moves image into another category + * (The given image data is only stored in the database if old and new category are different from each other) + * + * @param object $item Holds the data of the image to move, if it's not an object we will try to retrieve the data from the database + * @param int $catid_new The ID of the category to which the image should be moved + * @param int $catid_old The ID of the old category of the image + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + public function moveImage(&$item, $catid_new, $catid_old = 0) + { + jimport('joomla.filesystem.file'); + + // If we just have the image ID + if(!is_object($item)) + { + $id = intval($item); + $item = $this->getTable('joomgalleryimages'); + $item->load($id); + $catid_old = $item->catid; + } + + // If the image is already in the correct category return true + if($catid_new == $catid_old) + { + return true; + } + + $catpath_old = JoomHelper::getCatPath($catid_old); + $catpath_new = JoomHelper::getCatPath($catid_new); + + // Database query to check if there are other images which this + // thumbnail is assigned to and how many of them exist + $query = $this->_db->getQuery(true); + $query->select('COUNT(id)') + ->from(_JOOM_TABLE_IMAGES) + ->where('imgthumbname = \''.$item->imgthumbname.'\'') + ->where('id != '.$item->id) + ->where('catid = '.$catid_old); + $this->_db->setQuery($query); + $thumb_count = $this->_db->loadResult(); + + // Check if thumbnail already exists in source directory and + // if it doesn't already exist in destination directory. + // If that's the case the file will not be copied. + $thumb_created = false; + $thumb_source = $this->_ambit->get('thumb_path').$catpath_old.$item->imgthumbname; + $thumb_dest = $this->_ambit->get('thumb_path').$catpath_new.$item->imgthumbname; + if(JFile::exists($thumb_dest)) + { + JError::raiseNotice(0, JText::_('COM_JOOMGALLERY_EDITIMAGE_MSG_DEST_THUMB_ALREADY_EXISTS')); + + if($thumb_count && JFile::exists($thumb_source)) + { + JFile::delete($thumb_source); + } + } + else + { + if(!JFile::exists($thumb_source)) + { + JError::raiseWarning(500, JText::sprintf('COM_JOOMGALLERY_EDITIMAGE_MSG_SOURCE_THUMB_NOT_EXISTS', $thumb_source)); + + return false; + } + else + { + // If there is no image remaining in source directory + // which uses the file + if(!$thumb_count) + { + // Move the thumbnail + $result = JFile::move($thumb_source, $thumb_dest); + } + else + { + // Otherwise just copy the thumbnail in order that it remains in the source directory + $result = JFile::copy($thumb_source, $thumb_dest); + } + // If not succesful raise an error message and abort + if(!$result) + { + JError::raiseWarning(100, JText::sprintf('COM_JOOMGALLERY_EDITIMAGE_MSG_COULD_NOT_MOVE_THUMB', JPath::clean($thumb_dest))); + + return false; + } + + // Set control variable according to the successful move/copy procedure + $thumb_created = true; + } + } + + // Database query to check if there are other images which this + // file is assigned to and how many of them exist + $query->clear('where'); + $query->where('imgfilename = \''.$item->imgfilename.'\'') + ->where('id != '.$item->id) + ->where('catid = '.$catid_old); + $this->_db->setQuery($query); + $img_count = $this->_db->loadResult(); + + // Same procedure with the detail image + // In case of error roll previous copy/move procedure back + $img_created = false; + $img_source = $this->_ambit->get('img_path').$catpath_old.$item->imgfilename; + $img_dest = $this->_ambit->get('img_path').$catpath_new.$item->imgfilename; + if(JFile::exists($img_dest)) + { + JError::raiseNotice(0, JText::_('COM_JOOMGALLERY_EDITIMAGE_MSG_DEST_IMG_ALREADY_EXISTS')); + + if($img_count && JFile::exists($img_source)) + { + JFile::delete($img_source); + } + } + else + { + if(!JFile::exists($img_source)) + { + JError::raiseWarning(500, JText::sprintf('COM_JOOMGALLERY_EDITIMAGE_MSG_SOURCE_IMG_NOT_EXISTS', $img_source)); + + return false; + } + else + { + if(!$img_count) + { + $result = JFile::move($img_source, $img_dest); + } + else + { + $result = JFile::copy($img_source, $img_dest); + } + if(!$result) + { + if($thumb_created) + { + if(!$thumb_count) + { + JFile::move($thumb_dest, $thumb_source); + } + else + { + JFile::delete($thumb_dest); + } + } + + JError::raiseWarning(100, JText::sprintf('COM_JOOMGALLERY_EDITIMAGE_MSG_COULD_NOT_MOVE_IMG', JPath::clean($img_dest))); + + return false; + } + + // Set control variable according to the successful move/copy procedure + $img_created = true; + } + } + + // Go on with original image + $orig_source = $this->_ambit->get('orig_path').$catpath_old.$item->imgfilename; + $orig_dest = $this->_ambit->get('orig_path').$catpath_new.$item->imgfilename; + if(JFile::exists($orig_dest)) + { + JError::raiseNotice(0, JText::_('COM_JOOMGALLERY_EDITIMAGE_MSG_DEST_ORIG_ALREADY_EXISTS')); + + if($img_count && JFile::exists($orig_source)) + { + JFile::delete($orig_source); + } + } + else + { + if(JFile::exists($orig_source)) + { + if(!$img_count) + { + $result = JFile::move($orig_source, $orig_dest); + } + else + { + $result = JFile::copy($orig_source, $orig_dest); + } + if(!$result) + { + if($thumb_created) + { + if(!$thumb_count) + { + JFile::move($thumb_dest, $thumb_source); + } + else + { + JFile::delete($thumb_dest); + } + } + if($img_created) + { + if(!$img_count) + { + JFile::move($img_dest, $img_source); + } + else + { + JFile::delete($img_dest); + } + } + + JError::raiseWarning(100, JText::sprintf('COM_JOOMGALLERY_EDITIMAGE_MSG_COULD_NOT_MOVE_ORIG', JPath::clean($orig_dest))); + + return false; + } + } + } + + // If all folder operations for the image were successful + // modify the database entry + $item->catid = $catid_new; + $item->ordering = $item->getNextOrder('catid = '.$catid_new); + + // Make sure the record is valid + if(!$item->check()) + { + JError::raiseWarning($item->getError()); + + return false; + } + + // Store the entry to the database + if(!$item->store()) + { + JError::raiseWarning($item->getError()); + + return false; + } + + return true; + } + + /** + * Method to publish resp. unpublish an image + * + * @return boolean True on success, false otherwise + * @since 1.5.7 + */ + public function publish() + { + $row = $this->getTable('joomgalleryimages'); + + $row->load($this->_id); + + // Check whether we are allowed to edit the state of this image + if(!$this->_user->authorise('core.edit.state', _JOOM_OPTION.'.image.'.$row->id)) + { + $this->setError(JText::_('COM_JOOMGALLERY_IMAGE_MSG_EDITSTATE_NOT_PERMITTED')); + + return false; + } + + // Remember old state for check at the end whether the change was successful + $published = $row->published; + + $row->published = 1 - $row->published; + + if(!$row->check()) + { + $this->setError($row->getError()); + return false; + } + + if(!$row->store()) + { + $this->setError($row->getError()); + } + + // If publishing or unpublishung wasn't successful, return false + if($row->published == $published) + { + return false; + } + + return true; + } +} diff --git a/deployed/joomgallery/components/com_joomgallery/models/editcategory.php b/deployed/joomgallery/components/com_joomgallery/models/editcategory.php new file mode 100644 index 00000000..8f3df878 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/models/editcategory.php @@ -0,0 +1,1022 @@ +_user->get('id') && !$this->_config->get('jg_unregistered_permissions')) + { + throw new Exception(JText::_('COM_JOOMGALLERY_COMMON_MSG_YOU_ARE_NOT_LOGGED')); + } + + $array = JRequest::getVar('catid', 0, '', 'array'); + + $this->setId($array[0]); + } + + /** + * Method to set the category ID and wipe data + * + * @param int $id Category ID + * @return void + * @since 1.5.5 + */ + public function setId($id) + { + // Set ID and wipe data + $this->_id = intval($id); + $this->_category = null; + } + + /** + * Retrieves the category data + * + * @return object Holds the category data from the database + * @since 1.5.5 + */ + public function getCategory() + { + if($this->_loadCategory()) + { + if($this->_id) + { + // Check whether we are allowed to edit the category + $asset = _JOOM_OPTION.'.category.'.$this->_id; + if(!$this->_user->authorise('core.edit', $asset) && (!$this->_user->authorise('core.edit.own', $asset) || !$this->_category->owner || $this->_category->owner != $this->_user->get('id'))) + { + $this->_mainframe->redirect(JRoute::_('index.php?option=com_joomgallery&view=gallery', false), JText::_('COM_JOOMGALLERY_COMMON_MSG_NOT_ALLOWED_TO_EDIT_CATEGORY'), 'notice'); + } + } + + return $this->_category; + } + + return false; + } + + /** + * Method to check whether the category can have its state edited by the current user + * + * @param array Holds the data of the category + * @return boolean True if the current user is allowed to change the state of the category, false otherwise + * @since 2.0 + */ + protected function canEditState($data) + { + // Check for existing category + if(isset($data['cid']) && $data['cid']) + { + return $this->_user->authorise('core.edit.state', _JOOM_OPTION.'.category.'.(int) $data['cid']); + } + else + { + // Maybe it is a new category, so check against the parent category + if(isset($data['parent_id']) && $data['parent_id'] > 1) + { + return $this->_user->authorise('core.edit.state', _JOOM_OPTION.'.category.'.(int) $data['parent_id']); + } + else + { + // Default to component settings if neither category nor parent category known + if(!isset($data['parent_id']) || !$data['parent_id']) + { + // If parent_id is 0 we are displaying the form for a new category + // Changing the state fields shall be possible for that (while storing + // the category later on the correct permissions will be checked again + return true; + } + else + { + return $this->_user->authorise('core.edit.state', _JOOM_OPTION); + } + } + } + } + + /** + * Method to get the form for the category + * + * @param array Holds the data of the category (if available) + * @return mixed A JForm object on success, false on failure + * @since 2.0 + */ + public function getForm($data = array()) + { + // Don't change the order of the foolowing pathes + JForm::addFormPath(JPATH_COMPONENT.'/models/forms'); + JForm::addFieldPath(JPATH_COMPONENT_ADMINISTRATOR.'/models/fields'); + JForm::addFieldPath(JPATH_COMPONENT.'/models/fields'); + JForm::addRulePath(JPATH_COMPONENT_ADMINISTRATOR.'/models/rules'); + + $form = JForm::getInstance(_JOOM_OPTION.'.editcategory', 'editcategory'); + if(empty($form)) + { + return false; + } + + if(empty($data)) + { + $data = (array) $this->getCategory(); + } + + // Allow plugins to preprocess the form + JPluginHelper::importPlugin('joomgallery'); + $this->preprocessForm($form, $data); + + if(!$this->canEditState($data)) + { + // Disable fields for display + $form->setFieldAttribute('ordering', 'disabled', 'true'); + $form->setFieldAttribute('published', 'disabled', 'true'); + + // Unset the data of fields which we aren't allowed to change + $form->setFieldAttribute('ordering', 'filter', 'unset'); + $form->setFieldAttribute('published', 'filter', 'unset'); + } + + if(!$this->_config->get('jg_usercatacc')) + { + $form->setFieldAttribute('access', 'disabled', 'true'); + $form->setFieldAttribute('access', 'filter', 'unset'); + } + + return $form; + } + + /** + * Method to allow plugins to preprocess the form + * + * @param JForm $form A JForm object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import (defaults to "content"). + * @return void + * @since 2.1 + */ + protected function preprocessForm(JForm $form, $data, $group = 'content') + { + // Import the appropriate plugin group + JPluginHelper::importPlugin($group); + + // Get the dispatcher + $dispatcher = JDispatcher::getInstance(); + + // Trigger the form preparation event + $results = $dispatcher->trigger('onContentPrepareForm', array($form, $data)); + + // Check for errors encountered while preparing the form + if(count($results) && in_array(false, $results, true)) + { + // Get the last error + $error = $dispatcher->getError(); + + if(!($error instanceof Exception)) + { + throw new Exception($error); + } + } + } + + /** + * Method to validate the form data + * + * @param object $form The form to validate against + * @param array $data The data to validate + * @return mixed Array of filtered data if valid, false otherwise + * @since 2.0 + */ + protected function _validate($form, $data) + { + // Filter and validate the form data + $data = $form->filter($data); + $return = $form->validate($data); + + // Check for an error + if(JError::isError($return)) + { + $this->setError($return->getMessage()); + return false; + } + + // Check the validation results + if ($return === false) + { + // Get the validation messages from the form + foreach($form->getErrors() as $message) + { + $this->setError(JText::_($message)); + } + return false; + } + + return $data; + } + + /** + * Method to store a category + * + * @return int Category ID on success, boolean false otherwise + * @since 1.5.5 + */ + public function store() + { + $row = $this->getTable('joomgallerycategories'); + $data = JRequest::get('post', 2); + + // Creating a main category means creating + // a category in ROOT category + if($data['parent_id'] == 0) + { + $data['parent_id'] = 1; + } + + // Check for validation errors + $form = $this->getForm($data); + $data = $this->_validate($form, $data); + if($data === false) + { + return false; + } + + // Check whether it is a new category + if($cid = intval($data['cid'])) + { + $isNew = false; + + // Load category from the database + $row->load($cid); + + // Check whether we are allowed to edit it + $asset = _JOOM_OPTION.'.category.'.$cid; + if(!$this->_user->authorise('core.edit', $asset) && (!$this->_user->authorise('core.edit.own', $asset) || !$row->owner || $row->owner != $this->_user->get('id'))) + { + $this->_mainframe->redirect(JRoute::_('index.php?option=com_joomgallery&view=gallery', false), JText::_('COM_JOOMGALLERY_COMMON_MSG_NOT_ALLOWED_TO_EDIT_CATEGORY'), 'notice'); + } + + // Read old category name + $catname_old = $row->name; + // Read old parent assignment + $parent_old = $row->parent_id; + } + else + { + $isNew = true; + + $query = $this->_db->getQuery(true); + $query->select('COUNT(cid)') + ->from(_JOOM_TABLE_CATEGORIES) + ->where('owner = '.$this->_user->get('id')); + $this->_db->setQuery($query); + $count = $this->_db->loadResult(); + if($count >= $this->_config->get('jg_maxusercat') && $this->_user->get('id')) + { + $this->_mainframe->redirect(JRoute::_('index.php?view=usercategories', false), JText::_('COM_JOOMGALLERY_EDITCATEGORY_MSG_NOT_ALLOWED_CREATE_MORE_USERCATEGORIES'), 'notice'); + } + } + + // Bind the form fields to the category table + if(!$row->bind($data)) + { + JError::raiseError(0, $row->getError()); + return false; + } + + // If it's a new category or the category will be moved + // do an access check for the selected parent category + $valid_parent = true; + $row->parent_id = intval($row->parent_id); + if($isNew || $parent_old != $row->parent_id) + { + if($row->parent_id > 1) + { + // Get data of the parent category + $query = $this->_db->getQuery(true) + ->select('cid, owner') + ->from(_JOOM_TABLE_CATEGORIES) + ->where('cid = '.$row->parent_id); + $this->_db->setQuery($query); + $parent_category = $this->_db->loadObject(); + + if( !$parent_category + || ( !$this->_user->authorise('core.create', _JOOM_OPTION.'.category.'.$row->parent_id) + && ( !$this->_user->authorise('joom.create.inown', _JOOM_OPTION.'.category.'.$row->parent_id) + || !$parent_category->owner + || $parent_category->owner != $this->_user->get('id') + ) + ) + ) + { + $valid_parent = false; + } + } + else + { + if(!$this->_user->authorise('core.create', _JOOM_OPTION)) + { + $valid_parent = false; + } + } + } + + if($isNew) + { + // Check whether the user is allowed to store the category into the specified parent category or as a main category + if(!$valid_parent) + { + $this->_mainframe->redirect(JRoute::_('index.php?view=editcategory', false), JText::_('COM_JOOMGALLERY_EDITCATEGORY_MSG_NOT_ALLOWED_STORE_CATEGORY_IN_PARENT'), 'error'); + } + + // Determine location in category tree + if(!isset($data['ordering']) || !$data['ordering'] || $data['ordering'] == 'first-child') + { + $row->setLocation($data['parent_id'], 'first-child'); + } + else + { + if($data['ordering'] == 'last-child') + { + $row->setLocation($data['parent_id'], 'last-child'); + } + else + { + $row->setLocation($data['ordering'], 'after'); + } + } + + // Set the owner of the category + $row->owner = $this->_user->get('id'); + + // Make sure the record is valid + if(!$row->check()) + { + $this->setError($row->getError()); + return false; + } + + JFilterOutput::objectHTMLSafe($row->name); + + // Check if special characters of catname can be replaced for a valid catpath + // if resulting string is invalid set an error + $catpath = JoomFile::fixFilename($row->name); + if(JoomFile::checkValidFilename($row->name, $catpath) == false) + { + $this->setError(JText::_('COM_JOOMGALLERY_CATMAN_MSG_ERROR_INVALID_FOLDERNAME')); + return false; + } + + // Store the entry to the database in order to get the new ID + if(!$row->store()) + { + JError::raiseError(0, $row->getError()); + return false; + } + + if($row->parent_id > 1) + { + $parent_catpath = JoomHelper::getCatPath($row->parent_id); + $catpath = $parent_catpath . $catpath; + } + + // Add the category id to catpath + $catpath .= '_'.$row->cid; + + if(!$this->_createFolders($catpath)) + { + $this->setError(JText::_('COM_JOOMGALLERY_EDITCATEGORY_MSG_UNABLE_CREATE_FOLDERS')); + + // Delete the just stored database entry + $row->delete(); + + return false; + } + else + { + $row->catpath = $catpath; + + // Make sure the record is valid + if(!$row->check()) + { + $this->setError($row->getError()); + return false; + } + + // Store the entry to the database + if(!$row->store()) + { + JError::raiseError(0, $row->getError()); + return false; + } + } + + $this->_mainframe->triggerEvent('onContentAfterSave', array(_JOOM_OPTION.'.category', &$row, true)); + + // New category successfully created + return $row->cid; + } + + // Move the category folder, if parent assignment or category name changed + if($parent_old != $row->parent_id || $catname_old != $row->name) + { + // Check whether the user is allowed to move the category into the specified parent category + if(!$valid_parent) + { + // If not store the category in the old parent category and leave a message. + $row->parent_id = $parent_old; + + /*if(!$row->store()) + { + JError::raiseError(100, $row->getError()); + return false; + }*/ + $this->_mainframe->enqueueMessage(JText::_('COM_JOOMGALLERY_COMMON_MSG_NOT_ALLOWED_STORE_IMAGE_IN_CATEGORY'), 'notice'); + } + else + { + if($parent_old != $row->parent_id) + { + if(isset($data['ordering']) && $data['ordering'] != $data['cid']) + { + // Determine location in category tree + if(!$data['ordering'] || $data['ordering'] == 'first-child') + { + $row->setLocation($data['parent_id'], 'first-child'); + } + else + { + if($data['ordering'] == 'last-child') + { + $row->setLocation($data['parent_id'], 'last-child'); + } + else + { + $row->setLocation($data['ordering'], 'after'); + } + } + } + else + { + $row->setLocation($data['parent_id'], 'first-child'); + } + } + } + + // Save old path + $catpath_old = $row->catpath; + + JFilterOutput::objectHTMLSafe($row->name); + + // Check if special characters of catname can be replaced for a valid catpath + // if resulting string is invalid set an error + $catpath = JoomFile::fixFilename($row->name); + if(JoomFile::checkValidFilename($row->name, $catpath) == false) + { + $this->setError(JText::_('COM_JOOMGALLERY_COMMON_ERROR_CATEGORY_INVALID_FOLDERNAME')); + return false; + } + + // Add the category id to catpath + $catpath .= '_' . $row->cid; + + if($row->parent_id > 1) + { + $parent_catpath = JoomHelper::getCatPath($row->parent_id); + $catpath = $parent_catpath . $catpath; + } + + // Move folders, only if the catpath has changed + if($catpath_old != $catpath && !$this->_moveFolders($catpath_old, $catpath)) + { + $this->setError(JText::_('COM_JOOMGALLERY_EDITCATEGORY_MSG_UNABLE_MOVE_FOLDERS')); + return false; + } + // Update catpath in the database + $row->catpath = $catpath; + + // Modify catpath of all sub-categories in the database + $this->_updateNewCatpath($row->cid, $catpath_old, $catpath); + } + else + { + // Check whether ordering has changed + if(isset($data['ordering']) && $data['ordering'] != $row->cid) + { + // Determine location in category tree + if($data['ordering'] == 'first-child' || $data['ordering'] == 'last-child') + { + $row->setLocation($data['parent_id'], $data['ordering']); + } + else + { + // Check whether the new reference category is a + // valid child category of the current parent category + $this->_db->setQuery($this->_db->getQuery(true) + ->select('cid') + ->from(_JOOM_TABLE_CATEGORIES) + ->where('parent_id = '.$row->parent_id) + ->where('cid = '.$data['ordering'])); + if($this->_db->loadResult()) + { + $row->setLocation($data['ordering'], 'after'); + } + } + } + } + + // Make sure the record is valid + if(!$row->check()) + { + $this->setError($row->getError()); + return false; + } + + // Store the entry to the database + if(!$row->store()) + { + JError::raiseError(0, $row->getError()); + return false; + } + + $this->_mainframe->triggerEvent('onContentAfterSave', array(_JOOM_OPTION.'.category', &$row, false)); + + return $row->cid; + } + + /** + * Method to delete one or more categories + * + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + public function delete() + { + $row = $this->getTable('joomgallerycategories'); + + $row->load($this->_id); + + // Check whether we are allowed to delete this category + if(!$this->_user->authorise('core.delete', _JOOM_OPTION.'.category.'.$this->_id)) + { + throw new RuntimeException(JText::_('COM_JOOMGALLERY_CATEGORY_MSG_DELETE_NOT_PERMITTED')); + } + + $query = $this->_db->getQuery(true); + $query->select('COUNT(id)') + ->from(_JOOM_TABLE_IMAGES) + ->where('catid = '.$this->_id); + $this->_db->setQuery($query); + if($this->_db->loadResult()) + { + throw new RuntimeException(JText::sprintf('COM_JOOMGALLERY_EDITCATEGORY_MSG_CATEGORY_CONTAINS_IMAGES', $this->_id)); + } + + // Database query to check whether there are any sub-categories assigned + $query = $this->_db->getQuery(true); + $query->select('COUNT(cid)') + ->from(_JOOM_TABLE_CATEGORIES) + ->where('parent_id = '.$this->_id); + $this->_db->setQuery($query); + if($this->_db->loadResult()) + { + throw new RuntimeException(JText::sprintf('COM_JOOMGALLERY_EDITCATEGORY_MSG_CATEGORY_CONTAINS_SUBCATEGORIES', $this->_id)); + } + + $catpath = JoomHelper::getCatPath($this->_id); + if(!$this->_deleteFolders($catpath)) + { + JLog::add(JText::_('COM_JOOMGALLERY_EDITCATEGORY_MSG_UNABLE_DELETE_DIRECTORIES'), JLog::WARNING, 'jerror'); + } + + if(!$row->delete()) + { + throw new RuntimeException($row->getError()); + } + + // Reset the user state variable 'catid' for filtering in user panel + $this->_mainframe->setUserState('joom.userpanel.catfilter', 0); + + JPluginHelper::importPlugin('joomgallery'); + $this->_mainframe->triggerEvent('onContentAfterDelete', array(_JOOM_OPTION.'.category', $row)); + + // Category successfully deleted + return true; + } + + /** + * Loads the category data + * + * @return boolean True + * @since 1.5.5 + */ + protected function _loadCategory() + { + if(empty($this->_category)) + { + $row = $this->getTable('joomgallerycategories'); + + if($row->load($this->_id)) + { + $row->catpath = JoomHelper::getCatPath($this->_id); + + if($row->thumbnail) + { + $row->catimage_src = $this->_ambit->getImg('thumb_url', $row->thumbnail, null, $this->_id); + } + else + { + $row->catimage_src = 'media/system/images/blank.png'; + } + + if(!$this->_id) + { + $row->published = 1; + $row->access = $this->_mainframe->getCfg('access'); + } + } + else + { + $row->published = 1; + $row->access = $this->_mainframe->getCfg('access'); + } + + JPluginHelper::importPlugin('joomgallery'); + $this->_mainframe->triggerEvent('onContentPrepareData', array(_JOOM_OPTION.'.category', $row)); + + $this->_category = $row; + } + + return true; + } + + /** + * Update of category path in the database for sub-categories + * if a parent category has been moved or the name has changed. + * + * Recursive call to each level of depth. + * + * TODO: Use category structure for this + * + * @param string $catids_values ID(s) of the categories to update (comma separated) + * @param string $oldpath Former relative category path + * @param string $newpath New relative category path + * @return void + * @since 1.0.0 + */ + protected function _updateNewCatpath($catids_values, &$oldpath, &$newpath) + { + // Query for sub-categories with parent in $catids_values + $query = $this->_db->getQuery(true); + $query->select('cid') + ->from(_JOOM_TABLE_CATEGORIES) + ->where('parent_id IN ('.$catids_values.')'); + $this->_db->setQuery($query); + $subcatids = $this->_db->loadColumn(); + if($this->_db->getErrorNum()) + { + JError::raiseWarning(500, $this->_db->getErrorMsg()); + } + + // Nothing found, return + if(!count($subcatids)) + { + return; + } + + $row = JTable::getInstance('joomgallerycategories', 'Table'); + foreach($subcatids as $subcatid) + { + $row->load($subcatid); + $catpath = $row->catpath; + + // Replace former category path with the new one + $catpath = str_replace($oldpath.'/', $newpath.'/', $catpath); + + // Then save it + $row->catpath = $catpath; + if(!$row->store()) + { + JError::raiseError(500, $row->getError()); + } + } + + // Split the array in comma separated string + $catids_values = implode (',', $subcatids); + + // Call again with sub-categories as parent + $this->_updateNewCatpath($catids_values, $oldpath, $newpath); + } + + /** + * Creates the folders for a category + * + * @param string The category path for the category + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + protected function _createFolders($catpath) + { + $catpath = JPath::clean($catpath); + + // Create the folder of the category for the original images + if(!JFolder::create($this->_ambit->get('orig_path').$catpath)) + { + // If not successfull + return false; + } + else + { + // Copy an index.html file into the new folder + JoomFile::copyIndexHtml($this->_ambit->get('orig_path').$catpath); + + // Create the folder of the category for the detail images + if(!JFolder::create($this->_ambit->get('img_path').$catpath)) + { + // If not successful + JFolder::delete($this->_ambit->get('orig_path').$catpath); + return false; + } + else + { + // Copy an index.html file into the new folder + JoomFile::copyIndexHtml($this->_ambit->get('img_path').$catpath); + + // Create the folder of the category for the thumbnails + if(!JFolder::create($this->_ambit->get('thumb_path').$catpath)) + { + // If not successful + JFolder::delete($this->_ambit->get('orig_path').$catpath); + JFolder::delete($this->_ambit->get('img_path').$catpath); + return false; + } + else + { + // Copy an index.html file into the new folder + JoomFile::copyIndexHtml($this->_ambit->get('thumb_path').$catpath); + } + } + } + + return true; + } + + /** + * Moves folders of an existing category + * + * @param string $src The source category path + * @param string $dest The destination category path + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + protected function _moveFolders($src, $dest) + { + $orig_src = JPath::clean($this->_ambit->get('orig_path').$src); + $orig_dest = JPath::clean($this->_ambit->get('orig_path').$dest); + $img_src = JPath::clean($this->_ambit->get('img_path').$src); + $img_dest = JPath::clean($this->_ambit->get('img_path').$dest); + $thumb_src = JPath::clean($this->_ambit->get('thumb_path').$src); + $thumb_dest = JPath::clean($this->_ambit->get('thumb_path').$dest); + + // Move the folder of the category for the original images + $return = JFolder::move($orig_src, $orig_dest); + if($return !== true) + { + // If not successfull + JError::raiseWarning(100, $return); + return false; + } + else + { + // Move the folder of the category for the detail images + $return = JFolder::move($img_src, $img_dest); + if($return !== true) + { + // If not successful + JFolder::move($orig_dest, $orig_src); + JError::raiseWarning(100, $return); + return false; + } + else + { + // Move the folder of the category for the thumbnails + $return = JFolder::move($thumb_src, $thumb_dest); + if($return !== true) + { + // If not successful + JFolder::move($orig_dest, $orig_src); + JFolder::move($img_dest, $img_src); + JError::raiseWarning(100, $return); + return false; + } + } + } + + return true; + } + + /** + * Deletes folders of an existing category + * + * @param string $catpath The catpath of the category + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + protected function _deleteFolders($catpath) + { + if(!$catpath) + { + return false; + } + + $orig_path = JPath::clean($this->_ambit->get('orig_path').$catpath); + $img_path = JPath::clean($this->_ambit->get('img_path').$catpath); + $thumb_path = JPath::clean($this->_ambit->get('thumb_path').$catpath); + + // Delete the folder of the category for the original images + if(!JFolder::delete($orig_path)) + { + // If not successfull + return false; + } + else + { + // Delete the folder of the category for the detail images + if(!JFolder::delete($img_path)) + { + // If not successful + if(JFolder::create($orig_path)) + { + JoomFile::copyIndexHtml($orig_path); + } + + return false; + } + else + { + // Delete the folder of the category for the thumbnails + if(!JFolder::delete($thumb_path)) + { + // If not successful + if(JFolder::create($orig_path)) + { + JoomFile::copyIndexHtml($orig_path); + } + if(JFolder::create($img_path)) + { + JoomFile::copyIndexHtml($img_path); + } + + return false; + } + } + } + + return true; + } + + /** + * Method to publish resp. unpublish a category + * + * @return boolean True on success, false otherwise + * @since 1.5.7 + */ + public function publish() + { + $row = $this->getTable('joomgallerycategories'); + + $row->load($this->_id); + + // Check whether we are allowed to edit the state of this category + if(!$this->_user->authorise('core.edit.state', _JOOM_OPTION.'.category.'.$row->cid)) + { + $this->setError(JText::_('COM_JOOMGALLERY_CATEGORY_MSG_EDITSTATE_NOT_PERMITTED')); + + return false; + } + + // Remember old state for check at the end whether the change was successful + $published = $row->published; + + $row->published = 1 - $row->published; + + if(!$row->check()) + { + $this->setError($row->getError()); + return false; + } + + if(!$row->store()) + { + $this->setError($row->getError()); + } + + // If publishing or unpublishung wasn't successful, return false + if($row->published == $published) + { + return false; + } + + return true; + } + + /** + * Retrieves the data for creating the orderings drop down list + * + * @param int $parent Parent category which has to be included into the list independent of it's access state + * @return array An array of JHTML select options with the ordering numbers + * and the category names + * @since 1.5.7 + */ + public function getOrderings($parent = null) + { + if(empty($this->_orderings)) + { + $categories = JoomHelper::getAuthorisedCategories('core.create'); + + $allowed_categories = ''; + + // If the user is allowed to create main categories add '0' as an allowed parent category + if($this->_user->authorise('core.create', _JOOM_OPTION)) + { + $allowed_categories .= '1,'; + } + + foreach($categories as $category) + { + $allowed_categories .= $category->cid.','; + } + + if(!is_null($parent)) + { + $allowed_categories .= $parent; + } + else + { + $allowed_categories = trim($allowed_categories, ','); + } + + if(!$allowed_categories) + { + return array(); + } + + $query = $this->_db->getQuery(true); + $query->select('cid') + ->select('parent_id') + ->select('name') + ->from(_JOOM_TABLE_CATEGORIES) + ->where('parent_id IN ('.$allowed_categories.')') + ->where('lft > 0') + ->order('lft'); + $this->_db->setQuery($query); + if(!$this->_orderings = $this->_db->loadObjectList()) + { + $this->setError($this->_db->getError()); + return array(); + } + } + + return $this->_orderings; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/models/favourites.php b/deployed/joomgallery/components/com_joomgallery/models/favourites.php new file mode 100644 index 00000000..eb51386d --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/models/favourites.php @@ -0,0 +1,958 @@ +_config->get('jg_favourites') + || (!$this->_config->get('jg_usefavouritesforpubliczip') && !$this->_user->get('id')) + ) + { + $this->_mainframe->redirect(JRoute::_('index.php?view=gallery', false), JText::_('COM_JOOMGALLERY_COMMON_PERMISSION_DENIED'), 'notice'); + } + + // Set the image id + $view = JRequest::getCmd('view'); + $task = JRequest::getCmd('task'); + if( ($view != 'favourites' || $task == 'removeimage') + && $view != 'downloadzip' + && $task != 'removeall' + && $task != 'switchlayout' + && $task != 'createzip' + && $task != 'addimages' + ) + { + $id = JRequest::getInt('id'); + $this->setId($id); + } + + // Check whether we will work with the database or the session + if($this->_user->get('id') && $this->_config->get('jg_usefavouritesforzip') != 1) + { + $this->using_database = true; + $this->_output = 'COM_JOOMGALLERY_FAVOURITES_MSG_'; + + $query = $this->_db->getQuery(true) + ->select('piclist, layout') + ->from(_JOOM_TABLE_USERS) + ->where('uuserid = '.$this->_user->get('id')); + $this->_db->setQuery($query); + + if($row = $this->_db->loadObject()) + { + $this->user_exists = true; + $this->piclist = $row->piclist; + $this->layout = $row->layout; + } + else + { + $this->user_exists = false; + $this->piclist = null; + $this->layout = 0; + } + } + else + { + $this->using_database = false; + $this->_output = 'COM_JOOMGALLERY_FAVOURITES_ZIP_MSG_'; + + $this->piclist = $this->_mainframe->getUserState('joom.favourites.pictures'); + $this->layout = $this->_mainframe->getUserState('joom.favourites.layout'); + } + } + + /** + * Method to set the image id + * + * @param int Image ID number + * @return void + * @since 1.5.5 + */ + public function setId($id) + { + // Set new image ID if valid + if(!$id) + { + JError::raiseError(500, JText::_('COM_JOOMGALLERY_COMMON_NO_IMAGE_SPECIFIED')); + } + $this->_id = $id; + } + + /** + * Method to get the identifier + * + * @return int The image ID + * @since 1.5.5 + */ + public function getId() + { + return $this->_id; + } + + /** + * Method to get the current layout + * + * @return string The name of the current layout + * @since 1.5.5 + */ + public function getLayout() + { + return $this->layout; + } + + /** + * Method to add an image to the favourites or the zip download + * + * @return boolean True on success, false otherwise + * @since 1.0.0 + */ + public function addImage() + { + $query = $this->_db->getQuery(true) + ->select('id') + ->from(_JOOM_TABLE_IMAGES.' AS a') + ->leftJoin(_JOOM_TABLE_CATEGORIES.' AS c ON a.catid = c.cid') + ->where('a.id = '.$this->_id) + ->where('a.approved = 1') + ->where('a.published = 1') + ->where('a.access IN ('.implode(',', $this->_user->getAuthorisedViewLevels()).')') + ->where('c.access IN ('.implode(',', $this->_user->getAuthorisedViewLevels()).')') + ->where('c.published = 1'); + $this->_db->setQuery($query); + if(!$this->_db->loadResult()) + { + $this->setError('Stop Hacking attempt!'); + + return false; + } + + if(is_null($this->piclist)) + { + if($this->using_database) + { + if($this->user_exists) + { + $query->clear() + ->update(_JOOM_TABLE_USERS) + ->set('piclist = '.$this->_db->q($this->_id)) + ->where('uuserid = '.$this->_user->get('id')); + } + else + { + $query->clear() + ->insert(_JOOM_TABLE_USERS) + ->columns('uuserid, piclist') + ->values($this->_user->get('id').', '.$this->_db->q($this->_id)); + } + + $this->_db->setQuery($query); + $return = $this->_db->query(); + } + else + { + $this->_mainframe->setUserState('joom.favourites.pictures', $this->_id); + } + } + else + { + $piclist_array = explode(',', $this->piclist); + + if(in_array($this->_id, $piclist_array)) + { + // Image is already in there + $this->_mainframe->enqueueMessage($this->output('ALREADY_IN')); + + return true; + } + if($this->_config->get('jg_maxfavourites') && count($piclist_array) >= $this->_config->get('jg_maxfavourites')) + { + // Maximum number of images already reached + $this->setError($this->output('ALREADY_MAX')); + + return false; + } + + if($this->using_database) + { + $query->clear() + ->update(_JOOM_TABLE_USERS) + ->set('piclist = '.$this->_db->q($this->piclist.', '.$this->_id)) + ->where('uuserid = '.$this->_user->get('id')); + $this->_db->setQuery($query); + $return = $this->_db->query(); + } + else + { + $this->_mainframe->setUserState('joom.favourites.pictures', $this->piclist.','.$this->_id); + } + } + + if(isset($return) && !$return) + { + $this->setError($this->_db->getErrorMsg()); + + return false; + } + + $this->_mainframe->enqueueMessage($this->output('SUCCESSFULLY_ADDED')); + + $this->_mainframe->triggerEvent('onJoomAfterAddFavourite', array($this->_id)); + + return true; + } + + /** + * Method to add all images of a category (but none of the sub-categories) to the favourites or the zip download + * + * @param int The ID of the category from which all images should be added to the favourites or the zip download + * @return boolean True on success, false otherwise + * @since 1.0.0 + */ + public function addImages($catid) + { + $query = $this->_db->getQuery(true) + ->select('id') + ->from(_JOOM_TABLE_IMAGES.' AS a') + ->leftJoin(_JOOM_TABLE_CATEGORIES.' AS c ON a.catid = c.cid') + ->where('c.cid = '.(int) $catid) + ->where('a.approved = 1') + ->where('a.published = 1') + ->where('a.hidden = 0') + ->where('a.access IN ('.implode(',', $this->_user->getAuthorisedViewLevels()).')') + ->where('c.access IN ('.implode(',', $this->_user->getAuthorisedViewLevels()).')') + ->where('c.published = 1'); + $this->_db->setQuery($query); + if(!$images = $this->_db->loadColumn()) + { + $this->setError(JText::_('COM_JOOMGALLERY_FAVOURITES_NO_IMAGES_TO_ADD')); + + return false; + } + + if(is_null($this->piclist)) + { + if($this->_config->get('jg_maxfavourites') && count($images) > $this->_config->get('jg_maxfavourites')) + { + $this->setError($this->output('WOULD_EXCEED')); + + return false; + } + + if($this->using_database) + { + if($this->user_exists) + { + $query->clear() + ->update(_JOOM_TABLE_USERS) + ->set('piclist = '.$this->_db->q(implode(',', $images))) + ->where('uuserid = '.$this->_user->get('id')); + } + else + { + $query->clear() + ->insert(_JOOM_TABLE_USERS) + ->columns('uuserid, piclist') + ->values($this->_user->get('id').', '.$this->_db->q(implode(',', $images))); + } + + $this->_db->setQuery($query); + $return = $this->_db->query(); + } + else + { + $this->_mainframe->setUserState('joom.favourites.pictures', implode(',', $images)); + } + } + else + { + $piclist_array = explode(',', $this->piclist); + + $images = array_diff($images, $piclist_array); + + // If there is nothing in the difference we don't have to do anything + if(!count($images)) + { + return true; + } + + $new_piclist_array = array_unique(array_merge($piclist_array, $images)); + + if($this->_config->get('jg_maxfavourites') && count($new_piclist_array) > $this->_config->get('jg_maxfavourites')) + { + // Maximum number of images already reached + $this->_mainframe->enqueueMessage($this->output('WOULD_EXCEED')); + + return false; + } + + if($this->using_database) + { + $query->clear() + ->update(_JOOM_TABLE_USERS) + ->set('piclist = '.$this->_db->q(implode(',', $new_piclist_array))) + ->where('uuserid = '.$this->_user->get('id')); + $this->_db->setQuery($query); + $return = $this->_db->query(); + } + else + { + $this->_mainframe->setUserState('joom.favourites.pictures', implode(',', $new_piclist_array)); + } + } + + if(isset($return) && !$return) + { + $this->setError($this->_db->getErrorMsg()); + + return false; + } + + $this->_mainframe->triggerEvent('onJoomAfterAddFavourite', $images); + + return true; + } + + /** + * Method to remove an image from the favourites or the zip download + * + * @return boolean True on success, false otherwise + * @since 1.0.0 + */ + public function removeImage() + { + $piclist = explode(',', $this->piclist); + if(!in_array($this->_id, $piclist)) + { + $this->setError($this->output('NOT_IN')); + + return false; + } + + $new_piclist = array(); + foreach($piclist as $picid) + { + if($picid != $this->_id) + { + array_push($new_piclist, $picid); + } + } + + $query = $this->_db->getQuery(true); + + if(!count($new_piclist)) + { + $new_piclist = null; + $query->set('piclist = NULL'); + } + else + { + $new_piclist = implode(',', $new_piclist); + $query->set('piclist = '.$this->_db->q($new_piclist)); + } + + if($this->using_database) + { + $query->update(_JOOM_TABLE_USERS) + ->where('uuserid = '.$this->_user->get('id')); + $this->_db->setQuery($query); + if(!$this->_db->query()) + { + $this->setError($this->_db->getErrorMsg()); + + return false; + } + } + else + { + $this->_mainframe->setUserState('joom.favourites.pictures', $new_piclist); + } + + $this->_mainframe->triggerEvent('onJoomAfterRemoveFavourite', array($this->_id)); + + return true; + } + + /** + * Method to remove all images from the favourites or the zip download + * + * @return boolean True on success, false otherwise + * @since 1.0.0 + */ + public function removeAll() + { + if($this->using_database) + { + $query = $this->_db->getQuery(true) + ->update(_JOOM_TABLE_USERS) + ->set('piclist = NULL') + ->where('uuserid = '.$this->_user->get('id')); + $this->_db->setQuery($query); + if(!$this->_db->query()) + { + $this->setError($this->_db->getErrorMsg()); + + return false; + } + } + else + { + $this->_mainframe->setUserState('joom.favourites.pictures', null); + } + + $this->_mainframe->triggerEvent('onJoomAfterClearFavourites'); + + return true; + } + + /** + * Method to switch the current layout, currently switches the layout + * only if the user has already added some images to his list + * + * @return boolean True + * @since 1.0.0 + */ + public function switchLayout() + { + $layout = JRequest::getCmd('layout'); + if( + ($layout && $layout == 'list') + || + $this->layout + ) + { + $new_layout = 0; + } + else + { + $new_layout = 1; + } + + if($this->using_database) + { + $query = $this->_db->getQuery(true) + ->update(_JOOM_TABLE_USERS) + ->set('layout = '.$new_layout) + ->where('uuserid = '.$this->_user->get('id')); + $this->_db->setQuery($query); + $this->_db->query(); + } + else + { + $this->_mainframe->setUserState('joom.favourites.layout', $new_layout); + } + + return true; + } + + /** + * Method to create the zip archive with all selected images + * + * @return boolean True on success, false otherwise + * @since 1.0.0 + */ + public function createZip() + { + jimport('joomla.filesystem.file'); + jimport('joomla.filesystem.folder'); + jimport('joomla.filesystem.archive'); + + $zip_adapter = JArchive::getAdapter('zip'); + + // Check whether zip download is allowed + if( !$this->_config->get('jg_zipdownload') + && ($this->_user->get('id') || !$this->_config->get('jg_usefavouritesforpubliczip')) + ) + { + $this->_mainframe->redirect(JRoute::_('index.php?view=favourites', false), JText::_('COM_JOOMGALLERY_FAVOURITES_MSG_NOT_ALLOWED'), 'notice'); + } + + if(is_null($this->piclist)) + { + $this->_mainframe->redirect(JRoute::_('index.php?view=favourites', false), $this->output('NO_IMAGES'), 'notice'); + } + + $query = $this->_db->getQuery(true) + ->select('id') + ->select('catid') + ->select('imgfilename') + ->from(_JOOM_TABLE_IMAGES.' AS a') + ->from(_JOOM_TABLE_CATEGORIES.' AS c') + ->where('id IN ('.$this->piclist.')') + ->where('a.catid = c.cid') + ->where('a.published = 1') + ->where('a.approved = 1') + ->where('c.published = 1') + ->where('a.access IN ('.implode(',', $this->_user->getAuthorisedViewLevels()).')') + ->where('c.access IN ('.implode(',', $this->_user->getAuthorisedViewLevels()).')'); + + $this->_db->setQuery($query); + $rows = $this->_db->loadObjectList(); + + if(!count($rows)) + { + $this->_mainframe->redirect(JRoute::_('index.php?view=favourites', false), $this->output('NO_IMAGES'), 'notice'); + } + + // Name of the zip archive + $zipname = 'components/'._JOOM_OPTION.'/joomgallery_'.date('d_m_Y').'__'; + if($userid = $this->_user->get('id')) + { + $zipname .= $userid.'_'; + } + $zipname .= mt_rand(10000, 99999).'.zip'; + + $files = array(); + + if($this->_config->get('jg_downloadwithwatermark')) + { + $include_watermark = true; + + // Get the 'image' model + $imageModel = parent::getInstance('image', 'joomgallerymodel'); + + // Get the temp path for storing the watermarked image temporarily + if(!JFolder::exists($this->_ambit->get('temp_path'))) + { + $this->setError(JText::_('COM_JOOMGALLERY_UPLOAD_ERROR_TEMP_MISSING')); + + return false; + } + else + { + $tmppath = $this->_ambit->get('temp_path'); + } + } + else + { + $include_watermark = false; + } + + $categories = $this->_ambit->getCategoryStructure(); + foreach($rows as &$row) + { + if(!isset($categories[$row->catid])) + { + continue; + } + + // Get the original image if existent, otherwise the detail image + $orig = $this->_ambit->getImg('orig_path', $row->id); + $img = $this->_ambit->getImg('img_path', $row->id); + + if(file_exists($orig)) + { + $image = $orig; + } + else if(file_exists($img)) + { + $image = $img; + } + else + { + $image = null; + continue; + } + $files[$row->id]['name'] = $row->imgfilename; + + // Watermark the image before if needed + if($include_watermark) + { + // Get the image resource of watermarked image + $imgres = $imageModel->includeWatermark($image); + + // Start output buffering + ob_start(); + + // According to mime type output the watermarked image resource to file + $info = getimagesize($image); + switch($info[2]) + { + case 1: + imagegif($imgres); + break; + case 2: + imagejpeg($imgres); + break; + case 3: + imagepng($imgres); + break; + default: + JError::raiseError(404, JText::sprintf('COM_JOOMGALLERY_COMMON_MSG_MIME_NOT_ALLOWED', $mime)); + break; + } + + // Read the content from output buffer and fill the array element + $files[$row->id]['data'] = ob_get_contents(); + + // Delete the output buffer + ob_end_clean(); + } + else + { + $files[$row->id]['data'] = JFile::read($image); + } + + // Increase download counter for that image + $this->download($row->id); + } + + if(!count($files)) + { + $this->_mainframe->redirect(JRoute::_('index.php?view=favourites', false), $this->output('NO_IMAGES'), 'notice'); + } + + // Trigger event 'onJoomBeforeZipDownload' + $plugins = $this->_mainframe->triggerEvent('onJoomBeforeZipDownload', array(&$files)); + if(in_array(false, $plugins, true)) + { + $this->_mainframe->redirect(JRoute::_('index.php?view=favourites', false)); + } + + $createzip = $zip_adapter->create($zipname, $files); + + if(!$createzip) + { + // Workaround for servers with wwwwrun problem + JoomFile::chmod(JPATH_COMPONENT, '0777', true); + $createzip = $zip_adapter->create( $zipname, $files, 'zip'); + JoomFile::chmod(JPATH_COMPONENT, '0755', true); + } + + if(!$createzip) + { + $this->setError(JText::_('COM_JOOMGALLERY_FAVOURITES_ERROR_CREATEZIP')); + + return false; + } + + if($this->_user->get('id')) + { + if($this->user_exists) + { + $query = $this->_db->getQuery(true) + ->select('zipname') + ->from(_JOOM_TABLE_USERS) + ->where('uuserid = '.$this->_user->get('id')); + + $this->_db->setQuery($query); + + if($old_zip = $this->_db->loadResult()) + { + if(file_exists($old_zip)) + { + jimport('joomla.filesystem.file'); + JFile::delete($old_zip); + } + } + $query = $this->_db->getQuery(true) + ->update(_JOOM_TABLE_USERS) + ->set('time = NOW()') + ->set('zipname = '.$this->_db->q($zipname)) + ->where('uuserid = '.$this->_user->get('id')); + + $this->_db->setQuery($query); + } + else + { + $query = $this->_db->getQuery(true) + ->insert(_JOOM_TABLE_USERS) + ->set('uuserid = '.$this->_user->get('id')) + ->set('time = NOW()') + ->set('zipname = '.$this->_db->q($zipname)); + + $this->_db->setQuery($query); + } + } + else + { + $query = $this->_db->getQuery(true) + ->insert(_JOOM_TABLE_USERS) + ->set('time = NOW()') + ->set('zipname = '.$this->_db->q($zipname)); + + $this->_db->setQuery($query); + } + $this->_db->query(); + + $this->_mainframe->setUserState('joom.favourites.zipname', $zipname); + + // Message about new zip download + if(!$this->_user->get('username')) + { + $username = JText::_('COM_JOOMGALLERY_COMMON_GUEST'); + } + else + { + $username = $this->_config->get('jg_realname') ? $this->_user->get('name') : $this->_user->get('username'); + } + + if($this->_config->get('jg_msg_zipdownload')) + { + $imagefiles = implode(",\n", $files); + require_once JPATH_COMPONENT.'/helpers/messenger.php'; + $messenger = new JoomMessenger(); + $message = array( + 'subject' => JText::_('COM_JOOMGALLERY_MESSAGE_NEW_ZIPDOWNLOAD_SUBJECT'), + 'body' => JText::sprintf('COM_JOOMGALLERY_MESSAGE_NEW_ZIPDOWNLOAD_BODY', + $zipname, $username, $imagefiles), + 'mode' => 'zipdownload' + ); + $messenger->send($message); + } + + return true; + } + + /** + * Method to get all the favourites of the current user + * + * @return array An array of images data + * @since 1.5.5 + */ + public function getFavourites() + { + if($this->_loadFavourites()) + { + return $this->_favourites; + } + + return array(); + } + + /** + * Method to increment the download counter for an image. + * + * @param int $imgid Image Id. + * @return boolean True on success, false otherwise. + * @since 3.1 + */ + protected function download($imgid) + { + if($imgid) + { + $image = $this->getTable('joomgalleryimages'); + $image->download($imgid); + return true; + } + + return false; + } + + /** + * Method to auto-populate the model state. + * + * This method should only be called once per instantiation and is designed + * to be called on the first call to the getState() method unless the model + * configuration flag to ignore the request is set. + * + * Note. Calling getState in this method will result in recursion. + * + * @param string $ordering An optional ordering field. + * @param string $direction An optional direction (asc|desc). + * @return void + * @since 3.0 + */ + protected function populateState($ordering = 'imgtitle', $direction = 'asc') + { + $filter_fields = array( 'imgtitle', + 'hits', + 'downloads', + 'catid' + ); + + // Check if the ordering field is in the white list, otherwise use the incoming value + $value = $this->_mainframe->getUserStateFromRequest('joom.favourites.ordercol', 'filter_order', $ordering); + if(!in_array($value, $filter_fields)) + { + $value = $ordering; + $this->_mainframe->setUserState('joom.favourites.ordercol', $value); + } + $this->setState('list.ordering', $value); + + // Check if the ordering direction is valid, otherwise use the incoming value + $value = $this->_mainframe->getUserStateFromRequest('joom.favourites.orderdirn', 'filter_order_Dir', $direction); + if(!in_array(strtoupper($value), array('ASC', 'DESC', ''))) + { + $value = $direction; + $this->_mainframe->setUserState('joom.favourites.orderdirn', strotoupper($value)); + } + $this->setState('list.direction', $value); + } + + /** + * Method to load the image data from the database + * + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + protected function _loadFavourites() + { + // Load the images if they don't already exist + if(empty($this->_favourites)) + { + $query = $this->_db->getQuery(true) + ->select('*, a.catid, a.owner AS imgowner, '.JoomHelper::getSQLRatingClause('a').' AS rating'); + if($this->_config->get('jg_showcatcom')) + { + $subquery = $this->_db->getQuery(true) + ->select('COUNT(*)') + ->from(_JOOM_TABLE_COMMENTS) + ->where('cmtpic = a.id') + ->where('published = 1') + ->where('approved = 1'); + $query->select('('.$subquery.') AS comments'); + } + $query->from(_JOOM_TABLE_IMAGES.' AS a') + ->from(_JOOM_TABLE_CATEGORIES.' AS c') + ->where('a.catid = c.cid') + ->where('a.published = 1') + ->where('a.approved = 1') + ->where('c.published = 1') + ->where('a.access IN ('.implode(',', $this->_user->getAuthorisedViewLevels()).')') + ->where('c.access IN ('.implode(',', $this->_user->getAuthorisedViewLevels()).')') + ->where('c.hidden = 0') + ->where('c.in_hidden = 0'); + + if(is_null($this->piclist)) + { + $query->where('0'); + } + else + { + $query->where('a.id IN ('.$this->piclist.')'); + } + + $query->order($this->_db->escape($this->getState('list.ordering').' '.$this->getState('list.direction'))); + $this->_db->setQuery($query); + + $rows = $this->_db->loadObjectList(); + if($error = $this->_db->getErrorMsg()) + { + $this->setError($error); + + return false; + } + + $categories = $this->_ambit->getCategoryStructure(); + foreach($rows as $key => $row) + { + if(!isset($categories[$row->catid])) + { + unset($rows[$key]); + } + } + + $this->_favourites = $rows; + + // The list of favourites is filtered now, so that only valid images are chosen. + // So we store this list now in order to delete invalid images from the list. + if($this->using_database) + { + $ids = ''; + foreach($rows as $row) + { + $ids .= $row->id.','; + } + $query->clear() + ->update(_JOOM_TABLE_USERS) + ->set('piclist = '.((count($rows)) ? $this->_db->q(trim($ids, ',')) : 'NULL')) + ->where('uuserid = '.$this->_user->get('id')); + $this->_db->setQuery($query); + $this->_db->query(); + } + + return true; + } + } + + /** + * Returns a language string depending on the used mode for the zip download + * + * @param string The main part of the language constant to use + * @return string The translated string of the selected and completed language constant + * @since 1.5.5 + */ + public function output($msg) + { + return JText::_($this->_output.$msg); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/models/fields/index.html b/deployed/joomgallery/components/com_joomgallery/models/fields/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/models/fields/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/models/forms/ajaxupload.xml b/deployed/joomgallery/components/com_joomgallery/models/forms/ajaxupload.xml new file mode 100644 index 00000000..aff958c6 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/models/forms/ajaxupload.xml @@ -0,0 +1,120 @@ + +
    + +
    + + + + + + + + + + + + + + + +
    +
    +
    \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/models/forms/batchupload.xml b/deployed/joomgallery/components/com_joomgallery/models/forms/batchupload.xml new file mode 100644 index 00000000..b94aa231 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/models/forms/batchupload.xml @@ -0,0 +1,112 @@ + +
    + +
    + + + + + + + + + + + + + + +
    +
    +
    \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/models/forms/edit.xml b/deployed/joomgallery/components/com_joomgallery/models/forms/edit.xml new file mode 100644 index 00000000..d79e2ba1 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/models/forms/edit.xml @@ -0,0 +1,130 @@ + +
    +
    + + + + + + + + + + + + + + + + + +
    +
    \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/models/forms/editcategory.xml b/deployed/joomgallery/components/com_joomgallery/models/forms/editcategory.xml new file mode 100644 index 00000000..1df9c65e --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/models/forms/editcategory.xml @@ -0,0 +1,139 @@ + +
    +
    + + + + + + + + + + + + + + + + + + + + + + +
    +
    \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/models/forms/index.html b/deployed/joomgallery/components/com_joomgallery/models/forms/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/models/forms/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/models/forms/jupload.xml b/deployed/joomgallery/components/com_joomgallery/models/forms/jupload.xml new file mode 100644 index 00000000..5c83b9d0 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/models/forms/jupload.xml @@ -0,0 +1,90 @@ + +
    + +
    + + + + + + + + + + + + +
    +
    +
    \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/models/forms/quickedit.xml b/deployed/joomgallery/components/com_joomgallery/models/forms/quickedit.xml new file mode 100644 index 00000000..093cf84d --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/models/forms/quickedit.xml @@ -0,0 +1,56 @@ + +
    +
    + + + + + + +
    +
    \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/models/forms/upload.xml b/deployed/joomgallery/components/com_joomgallery/models/forms/upload.xml new file mode 100644 index 00000000..0af67e78 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/models/forms/upload.xml @@ -0,0 +1,113 @@ + +
    + +
    + + + + + + + + + + + + + + +
    +
    +
    \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/models/gallery.php b/deployed/joomgallery/components/com_joomgallery/models/gallery.php new file mode 100644 index 00000000..c818c52e --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/models/gallery.php @@ -0,0 +1,285 @@ +_loadCategories()) + { + return $this->_categories; + } + + return array(); + } + + /** + * Method to get the total number of categories + * + * @return int The total number of categories + * @since 1.5.5 + */ + public function getTotal() + { + // Let's load the categories if they doesn't already exist + if(empty($this->_total)) + { + $query = $this->_buildQuery(); + $this->_total = $this->_getListCount($query); + } + + return $this->_total; + } + + /** + * Returns the array of all available main categories + * of the gallery without empty categories + * + * @return array Categories objects array + * @since 1.5.7 + */ + public function getCategoriesWithoutEmpty() + { + if($this->_loadCategoriesWithoutEmpty()) + { + // We still have to select the categories according to the pagination + $limit = $this->_config->get('jg_catperpage');#JRequest::getVar('limit', 0, '', 'int'); + $limitstart = JRequest::getInt('limitstart', 0); + $cats = array_slice($this->_categorieswithoutempty, $limitstart, $limit); + + return $cats; + } + + return array(); + } + + /** + * Method to get the total number of categories without empty categories + * + * @return int The total number of categories without empty ones + * @since 1.5.7 + */ + public function getTotalWithoutEmpty() + { + // Let's calculate the number if it doesn't already exist + if(empty($this->_totalwithoutempty)) + { + if(!$this->_loadCategoriesWithoutEmpty()) + { + return 0; + } + } + + return $this->_totalwithoutempty; + } + + /** + * Method to get the data of a random image + * + * @access public + * @return object The data of a random image + * @since 1.5.5 + */ + public function getRandomImage($catid = 0, $random_catid = 0) + { + $query = $this->_db->getQuery(true) + ->select('*, c.access') + ->from(_JOOM_TABLE_IMAGES.' AS p') + ->leftJoin(_JOOM_TABLE_CATEGORIES.' AS c ON c.cid = p.catid'); + if($this->_config->get('jg_showrandomcatthumb') == 1) + { + $query->where('p.catid = '.$catid); + } + else + { + if($this->_config->get('jg_showrandomcatthumb') >= 2) + { + $query->where('p.catid = '.$random_catid); + } + } + $authorisedViewLevels = implode(',', $this->_user->getAuthorisedViewLevels()); + $query->where('p.access IN ('.$authorisedViewLevels.')') + ->where('p.published = 1') + ->where('p.approved = 1') + ->where('p.hidden != 1') + ->where('c.access IN ('.$authorisedViewLevels.')') + ->where('c.published = 1'); + $this->_db->setQuery($query); + + if(!$rows = $this->_db->loadObjectList()) + { + return false; + } + + $row = $rows[mt_rand(0, count($rows)-1)]; + + return $row; + } + + /** + * Loads the data of all available categories from the database + * + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + private function _loadCategories() + { + // Let's load the data if it doesn't already exist + if(empty($this->_categories)) + { + // Get the pagination request variables + $limit = $this->_config->get('jg_catperpage');#JRequest::getVar('limit', 0, '', 'int'); + $limitstart = JRequest::getInt('limitstart', 0); + + $query = $this->_buildQuery(); + + if(!$rows = $this->_getList($query, $limitstart, $limit)) + { + return false; + } + + $this->_categories = $rows; + } + + return true; + } + + /** + * Loads the data of all available categories from the database + * and checks whether the categories are empty. + * This method stores only the categories which aren't empty after that. + * + * @return boolean True on success, false otherwise + * @since 1.5.7 + */ + private function _loadCategoriesWithoutEmpty() + { + // Let's load the data if it doesn't already exist + if(empty($this->_categorieswithoutempty)) + { + $query = $this->_buildQuery(); + if(!$cats = $this->_getList($query)) + { + return false; + } + + foreach($cats as $key => $cat) + { + // Get all sub-categories for each category which contain images + $show_all = $this->_config->get('jg_showrestrictedcats'); + $subcategories = JoomHelper::getAllSubCategories($cat->cid, true, false, $show_all); + if(!count($subcategories)) + { + unset($cats[$key]); + } + } + + $this->_categorieswithoutempty = $cats; + $this->_totalwithoutempty = count($cats); + } + + return true; + } + + /** + * Returns the query for loading all available categories of the gallery + * + * @return string The query to be used to retrieve the categories from the database + * @since 1.5.5 + */ + private function _buildQuery() + { + $query = $this->_db->getQuery(true) + ->select('c.*') + ->from(_JOOM_TABLE_CATEGORIES.' AS c'); + + // Join over the images if necessary + if($this->_config->get('jg_showcatthumb') >= 2) + { + $query->select('i.id, i.catid, i.imgthumbname, i.hidden AS imghidden') + ->leftJoin(_JOOM_TABLE_IMAGES.' AS i ON ( c.thumbnail = i.id + AND i.published = 1 + AND i.approved = 1 + AND i.access IN ('.implode(',', $this->_user->getAuthorisedViewLevels()).'))'); + } + + $query->where('c.published = 1') + ->where('c.hidden = 0') + ->where('c.parent_id = 1'); + + if(!$this->_config->get('jg_showrestrictedcats')) + { + $query->where('c.access IN ('.implode(',', $this->_user->getAuthorisedViewLevels()).')'); + } + + if($this->_config->get('jg_hideemptycats')) + { + $query->where(' (((SELECT COUNT(id) FROM '._JOOM_TABLE_IMAGES.' AS i WHERE i.catid = c.cid) != 0) + OR + ((SELECT COUNT(cid) FROM '._JOOM_TABLE_CATEGORIES.' AS sc WHERE sc.parent_id = c.cid) != 0))'); + } + + if($this->_config->get('jg_ordercatbyalpha')) + { + $query->order('c.name'); + } + else + { + $query->order('c.lft'); + } + + return $query; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/models/image.php b/deployed/joomgallery/components/com_joomgallery/models/image.php new file mode 100644 index 00000000..82aa4c55 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/models/image.php @@ -0,0 +1,599 @@ +_id; + } + + /** + * Method to get the image data + * + * @param int $id ID of the image to display + * @return object The image data + * @since 1.5.5 + */ + public function getImage($id) + { + $id = (int) $id; + + // Set new image ID if valid and wipe data + if(!$id) + { + $this->setError(JText::_('COM_JOOMGALLERY_COMMON_NO_IMAGE_SPECIFIED')); + + return false; + } + + $this->_id = $id; + $this->_image = null; + + if(!$this->_loadImage()) + { + return false; + } + + return $this->_image; + } + + /** + * Method to increment the hit counter for the image + * + * @param int $id Image ID to use if no image data was loaded in the object afore + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + public function hit($id = null) + { + if($id) + { + $this->_id = $id; + } + + if($this->_id && !$this->countstop()) + { + $image = $this->getTable('joomgalleryimages'); + $image->hit($this->_id); + + return true; + } + + return false; + } + + /** + * Method to increment the download counter for the image + * + * @param int $id Image ID to use if no image data was loaded in the object afore. + * @return boolean True on success, false otherwise. + * @since 3.1 + */ + public function download($id = null) + { + if($id) + { + $this->_id = $id; + } + + if($this->_id) + { + $image = $this->getTable('joomgalleryimages'); + $image->download($this->_id); + + return true; + } + + return false; + } + + /** + * Method to check whether the hit counter should be incremented + * + * @return boolean True, if the hit counter is locked, false otherwise + * @since 1.5.5 + */ + public function countstop() + { + $session = JFactory::getSession(); + $session_id = $session->getToken(); + + $stoptime = $this->_mainframe->getCfg('lifetime') * 60; + $ip = $_SERVER['REMOTE_ADDR']; + + // Delete all dated entries + $query = $this->_db->getQuery(true) + ->delete(_JOOM_TABLE_COUNTSTOP) + ->where('NOW() > date_add(cstime, interval '.(int) $stoptime.' SECOND)'); + $this->_db->setQuery($query); + $this->_db->query(); + + // Check whether entry exists + $query->clear() + ->select('COUNT(cspicid)') + ->from(_JOOM_TABLE_COUNTSTOP) + ->where('cssessionid = '.$this->_db->q($session_id)) + ->where('csip = '.$this->_db->q($ip)) + ->where('cspicid = '.$this->_id); + $this->_db->setQuery($query); + + if($this->_db->loadResult()) + { + // Lock the counter + return true; + } + else + { + // New entry + $query->clear() + ->insert(_JOOM_TABLE_COUNTSTOP) + ->columns('csip, cssessionid, cspicid, cstime') + ->values($this->_db->q($ip).','.$this->_db->q($session_id).','.$this->_id.', NOW()'); + $this->_db->setQuery($query); + $this->_db->query(); + + return false; + } + } + + /** + * Method to check whether a given image is a gif file + * + * @param string $file Path to the image to check + * @return boolean True, if the given image is a gif file, false otherwise + * @since 1.5.5 + */ + public function isGif($file) + { + jimport('joomla.filesystem.file'); + + // Reads file content into string + $filecontents = JFile::read($file); + $str_loc = 0; + $count = 0; + + // Checks if there is more than one frame + while($count < 2) + { + $where1 = strpos($filecontents, "\x00\x21\xF9\x04", $str_loc); + if(!$where1) + { + break; + } + else + { + $str_loc = $where1+1; + $where2 = strpos($filecontents, "\x00\x2C", $str_loc); + if(!$where2) + { + break; + } + else + { + if($where1+8 == $where2) + { + $count++; + } + $str_loc = $where2+1; + } + } + } + + // Returns true if more then one frame is found + if($count > 1) + { + return true; + } + + return false; + } + + /** + * Method to include the watermark selected in + * the configuration manager into a given image + * + * @param string $file Path to the image into which the watermark shall be included + * @param resource $src_img GD image resource, will be used instead of $file if it is set + * @return resource image resource + * @since 1.5.5 + */ + public function includeWatermark($file, $src_img = null, $cropwidth = 0, $cropheight = 0) + { + // Path to the watermarkfile + $watermark = JPath::clean($this->_ambit->get('wtm_path').$this->_config->get('jg_wmfile')); + + // Checks if watermark file is existent + if(!JFile::exists($watermark)) + { + $this->setError(JText::_('COM_JOOMGALLERY_COMMON_ERROR_WATERMARK_NOT_EXIST')); + + return false; + } + + // Gets information of the image (height, width, mime) + if(!$src_img) + { + $info_img = getimagesize($file); + } + else + { + $info_img = array(0 => imagesx($src_img), 1 => imagesy($src_img)); + } + + $info_wat = getimagesize($watermark); + + switch($info_wat[2]) + { + case 1: + $watermark = imagecreatefromgif($watermark); + $mime_wat = 'image/gif'; + break; + case 2: + $watermark = imagecreatefromjpeg($watermark); + $mime_wat = 'image/jpeg'; + break; + case 3: + $watermark = imagecreatefrompng($watermark); + $mime_wat = 'image/png'; + break; + default: + $this->setError(JText::sprintf('COM_JOOMGALLERY_COMMON_MSG_MIME_NOT_ALLOWED', $info_wat[2])); + + return false; + } + + $watermarkzoom = $this->_config->get('jg_watermarkzoom'); + + if($watermarkzoom) + { + $watermarksize = $this->_config->get('jg_watermarksize'); + + if($watermarksize <= 0) + { + $watermarksize = 1; + } + elseif($watermarksize > 100) + { + $watermarksize = 100; + } + + $widthwm = $info_wat[0]; + $heightwm = $info_wat[1]; + + if($watermarkzoom == 1) + { + // Resize by height + $newheight_watermark = $info_img[1] * $watermarksize / 100; + $newwidth_watermark = $newheight_watermark * $widthwm / $heightwm; + + if($newwidth_watermark > $info_img[0]) + { + $newwidth_watermark = $info_img[0]; + } + } + else + { + // Resize by width + $newwidth_watermark = $info_img[0] * $watermarksize / 100; + $newheight_watermark = $newwidth_watermark * $heightwm / $widthwm; + + if($newheight_watermark > $info_img[1]) + { + $newheight_watermark = $info_img[1]; + } + } + + $newwatermark = ImageCreateTrueColor($newwidth_watermark, $newheight_watermark); + imagealphablending($newwatermark, false); + imagecopyresampled($newwatermark, $watermark, 0, 0, 0, 0, $newwidth_watermark, $newheight_watermark, $widthwm, $heightwm); + + $info_wat[0] = $newwidth_watermark; + $info_wat[1] = $newheight_watermark; + + imagedestroy($watermark); + + $watermark = $newwatermark; + } + + // Gets the position of the watermark + $position = $this->_config->get('jg_watermarkpos'); + + // Position x + switch(($position - 1) % 3) + { + case 1: + $pos_x = round(($info_img[0] - $info_wat[0]) / 2, 0); + break; + case 2: + $pos_x = $info_img[0] - $info_wat[0]; + break; + default: + $pos_x = 0; + break; + } + + // Position y + switch(floor(($position - 1) / 3)) + { + case 1: + $pos_y = round(($info_img[1] - $info_wat[1]) / 2, 0); + break; + case 2: + $pos_y = $info_img[1] - $info_wat[1]; + break; + default: + $pos_y = 0; + break; + } + + if(!$src_img) + { + switch($info_img[2]) + { + case 1: + $src_img = imagecreatefromgif($file); + $mime_img = 'image/gif'; + break; + case 2: + $src_img = imagecreatefromjpeg($file); + $mime_img = 'image/jpeg'; + break; + case 3: + $src_img = imagecreatefrompng($file); + $mime_img = 'image/png'; + break; + default: + $this->setError(JText::sprintf('COM_JOOMGALLERY_COMMON_MSG_MIME_NOT_ALLOWED', $info_img[2])); + + return false; + } + } + + // Check if image is smaller than watermark and return image without watermark + if($info_img[0] < $info_wat[0] || $info_img[1] < $info_wat[1]) + { + imagedestroy($watermark); + + return $src_img; + } + + imagealphablending($src_img, true); + imagecopyresampled($src_img, $watermark, $pos_x, $pos_y, 0, 0, $info_wat[0], $info_wat[1], $info_wat[0], $info_wat[1]); + imagedestroy($watermark); + + return $src_img; + } + + /** + * Method to load image data + * + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + protected function _loadImage() + { + if(!$this->_id) + { + return false; + } + + // Load the image data if it doesn't already exist + if(empty($this->_image)) + { + $query = $this->_db->getQuery(true) + ->select('a.*, a.owner AS imgowner, c.*') + ->from(_JOOM_TABLE_IMAGES.' AS a') + ->from(_JOOM_TABLE_CATEGORIES.' AS c') + ->from(_JOOM_TABLE_CATEGORIES.' AS p') + ->where('a.id = '.$this->_id) + ->where('a.published = 1') + ->where('a.approved = 1') + ->where('c.published = 1') + ->where('c.cid = a.catid') + ->where('c.lft BETWEEN p.lft AND p.rgt') + ->where('p.cid != 1') + ->where('a.access IN ('.implode(',', $this->_user->getAuthorisedViewLevels()).')') + ->where('c.access IN ('.implode(',', $this->_user->getAuthorisedViewLevels()).')') + ->where('p.access IN ('.implode(',', $this->_user->getAuthorisedViewLevels()).')') + ->where('(p.password = '.$this->_db->q('').' OR p.cid IN ('.implode(',', $this->_mainframe->getUserState('joom.unlockedCategories', array(0))).'))') + ->group('a.id') + ->having('COUNT(p.cid) >= c.level'); + $this->_db->setQuery($query); + + if(!$row = $this->_db->loadObject()) + { + $this->setError(JText::sprintf('Image with ID %d not found', $this->_id)); + + return false; + } + + $this->_image = $row; + + return true; + } + + return true; + } + + /** + * Method to crop a image + * + * @param string $img Path to image + * @param int $cropwidth Width of resulting image + * @param int $cropheight Height of resulting image + * @param int $croppos Offset position of cropping window + * @param int $offsetx Offset x-coordinate + * @param int $offsety Offset y-coordinate + * @return image Image ressource of cropped image or image if no cropping + * false if no cropping has been done + * @since 1.5.6 + */ + public function cropImage(&$img, &$cropwidth, &$cropheight, &$croppos, $offsetx = 0, $offsety = 0) + { + // Get information of image + $imginfo = getimagesize($img); + // Height/width + $srcWidth = $imginfo[0]; + $srcHeight = $imginfo[1]; + $srcImgtype = $imginfo[2]; + + // If both crop settings identical to the source dimensions, return null + if($srcWidth == $cropwidth && $srcHeight == $cropheight) + { + return null; + } + + if($croppos) + { + // Calculate the offsets for cropping the source image according + // to thumbposition + switch($croppos) + { + // Right upper corner + case 1: + $offsetx = floor($srcWidth - $cropwidth); + $offsety = 0; + break; + // Left lower corner + case 3: + $offsetx = 0; + $offsety = floor($srcHeight - $cropheight); + break; + // Right lower corner + case 4: + $offsetx = floor($srcWidth - $cropwidth); + $offsety = floor($srcHeight - $cropheight); + break; + // default center + default: + $offsetx = floor(($srcWidth - $cropwidth) * 0.5); + $offsety = floor(($srcHeight - $cropheight) * 0.5); + break; + } + } + + switch($srcImgtype) + { + // GIF + case 1: + $src_img = imagecreatefromgif($img); + break; + // JPEG + case 2: + $src_img = imagecreatefromjpeg($img); + break; + // PNG + case 3: + $src_img = imagecreatefrompng($img); + break; + default: + $src_img = imagecreatefromjpeg($img); + break; + } + + $cropimg = imagecreatetruecolor($cropwidth, $cropheight); + + // Check if the cropped image should be filled with background color + if($cropwidth > $srcWidth || $cropheight > $srcHeight) + { + // Get background color for cropped image + $cropbgcol = $this->_config->get('jg_dyncropbgcol'); + if(!$cropbgcol || in_array($cropbgcol, array('none', 'transparent'))) + { + $cropbgcol = 'FFFFFF'; + } + elseif($cropbgcol['0'] == '#') + { + $cropbgcol = substr($cropbgcol, 1); + } + + // Calculate a rgb code from hex value + $rgb[0] = hexdec(substr($cropbgcol, 0, 2)); + $rgb[1] = hexdec(substr($cropbgcol, 2, 2)); + $rgb[2] = hexdec(substr($cropbgcol, 4, 2)); + + // Allocate the color and fill the background of cropped image + $bgcolor=imagecolorallocate($cropimg, $rgb[0], $rgb[1], $rgb[2]); + imagefill($cropimg, 0, 0, $bgcolor); + } + + $dst_x = 0; + $dst_y = 0; + $src_w = $cropwidth; + $src_h = $cropheight; + + // The starting position '$offsetx' for the crop must be within the source image + if($offsetx < 0 || $offsetx > $srcWidth) + { + $offsetx = 0; + } + // Check, if the cropped image width will be larger than the source image width + if($cropwidth > $srcWidth) + { + // Center source image horizontal + $dst_x = floor(($cropwidth - $srcWidth) * 0.5); + // Reduce width to copy to the source image width + $src_w = $srcWidth; + } + // The starting position '$offsety' for the crop must be within the source image + if($offsety < 0 || $offsety > $srcHeight) + { + $offsety = 0; + } + // Check, if the cropped image height will be larger than the source image height + if($cropheight > $srcHeight) + { + // Center source image vertical + $dst_y = floor(($cropheight - $srcHeight) * 0.5); + // Reduce height to copy to the source image height + $src_h = $srcHeight; + } + + imagecopy($cropimg, $src_img, $dst_x, $dst_y, $offsetx, $offsety, $src_w, $src_h); + + return $cropimg; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/models/index.html b/deployed/joomgallery/components/com_joomgallery/models/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/models/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/models/mini.php b/deployed/joomgallery/components/com_joomgallery/models/mini.php new file mode 100644 index 00000000..db734e34 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/models/mini.php @@ -0,0 +1,210 @@ +_images)) + { + $limitstart = JRequest::getInt('limitstart'); + $limit = JRequest::getInt('limit'); + + $query = $this->_buildQuery(); + + if(!$this->_images = $this->_getList($query, $limitstart, $limit)) + { + $this->_images = array(); + } + } + + return $this->_images; + } + + /** + * Method to get the total number of images + * + * @return int The total number of images + * @since 1.5.5 + */ + public function getTotalImages() + { + // Let's load the categories if they doesn't already exist + if (empty($this->_total)) + { + $query = $this->_buildQuery(); + $this->_total = $this->_getListCount($query); + } + + return $this->_total; + } + + /** + * Method to get categories in which the user is allowed to upload images out of a set of given category IDs + * + * @param array An array of category IDs to check + * @return array An array holding all the relevant categories + * since 1.5.7 + */ + public function getUploadCategories($catids) + { + JArrayHelper::toInteger($catids); + + $query = $this->_db->getQuery(true) + ->select('cid, name, level, owner') + ->from(_JOOM_TABLE_CATEGORIES) + ->where('cid IN ('.implode(',', $catids).')') + ->order('lft ASC'); + $this->_db->setQuery($query); + if(!$categories = $this->_db->loadObjectList()) + { + return array(); + } + + $results = array(); + foreach($categories as $category) + { + $asset = _JOOM_OPTION.'.category.'.$category->cid; + if( $this->_user->authorise('joom.upload', $asset) + || ($this->_user->authorise('joom.upload.inown', $asset) && $category->owner && $this->_user->get('id') == $category->owner) + ) + { + $category->path = str_repeat('- ', $category->level).$category->name; + $results[] = $category; + } + } + + return $results; + } + + /** + * Method to get categories in which the user is allowed to create sub-categories out of a set of given category IDs + * + * @param array An array of category IDs to check + * @return array An array holding all the relevant categories + * since 1.5.7 + */ + public function getParentCategories($catids) + { + JArrayHelper::toInteger($catids); + + $query = $this->_db->getQuery(true) + ->select('cid, name, level, owner') + ->from(_JOOM_TABLE_CATEGORIES) + ->where('cid IN ('.implode(',', $catids).')') + ->order('lft ASC'); + $this->_db->setQuery($query); + if(!$categories = $this->_db->loadObjectList()) + { + return array(); + } + + $results = array(); + foreach($categories as $category) + { + $asset = _JOOM_OPTION.'.category.'.$category->cid; + if( $this->_user->authorise('core.create', $asset) + || ($this->_user->authorise('joom.create.inown', $asset) && $category->owner && $this->_user->get('id') == $category->owner) + ) + { + $category->path = str_repeat('- ', $category->level).$category->name; + $results[] = $category; + } + } + + return $results; + } + + /** + * Returns the query for loading the images + * + * @return string The query to be used to retrieve the images data from the database + * @since 1.5.5 + */ + protected function _buildQuery() + { + $query = $this->_db->getQuery(true) + ->select('jg.id, jg.catid, jg.imgtitle, jg.imgthumbname') + ->from(_JOOM_TABLE_IMAGES.' AS jg'); + + // Join over the categories + $query->select('jgc.name') + ->leftJoin(_JOOM_TABLE_CATEGORIES.' AS jgc ON jgc.cid = jg.catid'); + + // Ensure that image may be seen later on + if($this->_mainframe->getUserStateFromRequest('joom.mini.type', 'type', '', 'cmd') != 'category') + { + $query->where('jgc.published = 1'); + } + + $query->where('jg.published = 1') + ->where('jg.approved = 1') + ->where('jg.access IN ('.implode(',', $this->_user->getAuthorisedViewLevels()).')') + ->where('jgc.access IN ('.implode(',', $this->_user->getAuthorisedViewLevels()).')'); + + if($this->_mainframe->getUserState('joom.mini.extended') != 0 && !$this->_mainframe->getUserState('joom.mini.showhidden')) + { + $query->where('jg.hidden = 0') + ->where('jgc.hidden = 0') + ->where('jgc.in_hidden = 0'); + } + + // Filter by category + $catid = $this->_mainframe->getUserStateFromRequest('joom.mini.catid', 'catid', 0, 'int'); + if($catid || JRequest::getCmd('type') == 'category') + { + $query->where('jg.catid = '.$catid); + } + + // Filter by search + $search = $this->_mainframe->getUserStateFromRequest('joom.mini.search', 'search', '', 'string'); + if($search) + { + $search = $this->_db->escape($search); + $query->where('(LOWER(jg.imgtitle) LIKE \'%'.$search.'%\' OR LOWER(jg.imgtext) LIKE \'%'.$search.'%\')'); + } + + $query->order('jg.imgtitle ASC, jg.ordering ASC'); + + return $query; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/models/nametags.php b/deployed/joomgallery/components/com_joomgallery/models/nametags.php new file mode 100644 index 00000000..dad23533 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/models/nametags.php @@ -0,0 +1,310 @@ +setId((int)$id); + } + + /** + * Method to set the image ID + * + * @param int Image ID number + * @since 1.5.5 + */ + public function setId($id) + { + // Set new image ID if valid + if(!$id) + { + JError::raiseError(500, JText::_('COM_JOOMGALLERY_COMMON_NO_IMAGE_SPECIFIED')); + } + $this->_id = $id; + } + + /** + * Method to get the image ID + * + * @return int The image ID + * @since 1.5.5 + */ + public function getId() + { + return $this->_id; + } + + /** + * Method to save a name tag + * + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + public function save() + { + $yvalue = JRequest::getInt('yvalue', 0, 'post'); + $xvalue = JRequest::getInt('xvalue', 0, 'post'); + $height = $this->_config->get('jg_nameshields_height'); + + // Access check + if(!$by = $this->_user->get('id')) + { + JError::raiseError(500, JText::_('COM_JOOMGALLERY_COMMON_PERMISSION_DENIED')); + } + + // Check for hacking attempt + $authorised_viewlevels = implode(',', $this->_user->getAuthorisedViewLevels()); + + $query = $this->_db->getQuery(true) + ->select('c.cid') + ->from(_JOOM_TABLE_IMAGES.' AS a') + ->leftJoin(_JOOM_TABLE_CATEGORIES.' AS c ON c.cid = a.catid') + ->where('a.published = 1') + ->where('a.approved = 1') + ->where('a.id = '.$this->_id) + ->where('a.access IN ('.$authorised_viewlevels.')') + ->where('c.access IN ('.$authorised_viewlevels.')'); + + $this->_db->setQuery($query); + if(!$result = $this->_db->loadResult()) + { + die('Hacking attempt, aborted!'); + } + + $categories = $this->_ambit->getCategoryStructure(); + if(!isset($categories[$result])) + { + die('Hacking attempt, aborted!'); + } + + if($this->_config->get('jg_nameshields_others')) + { + $userid = JRequest::getInt('userid'); + } + else + { + $userid = $by; + } + + // Check whether an existing user was selected + $user = JFactory::getUser($userid); + if(!is_object($user)) + { + $this->setError(JText::_('COM_JOOMGALLERY_DETAIL_NAMETAGS_MSG_ERROR_SAVING')); + return false; + } + + $query = $this->_db->getQuery(true) + ->select('nid') + ->from(_JOOM_TABLE_NAMESHIELDS) + ->where('npicid = '.$this->_id) + ->where('nuserid = '.$userid); + $this->_db->setQuery($query); + + if($this->_db->loadResult()) + { + if($userid == $by) + { + $this->setError(JText::_('COM_JOOMGALLERY_DETAIL_NAMETAGS_MSG_YOU_ARE_ALREADY_TAGGED')); + } + else + { + $this->setError(JText::_('COM_JOOMGALLERY_DETAIL_NAMETAGS_MSG_USER_ALREADY_TAGGED')); + } + return false; + } + + $length = strlen($user->get('username')) * $this->_config->get('jg_nameshields_width'); + + if(($xvalue < $height) && ($yvalue < $length)) + { + $this->setError(JText::_('COM_JOOMGALLERY_DETAIL_NAMETAGS_MSG_NOT_SAVED')); + return false; + } + + $query->clear() + ->select('MIN(nzindex)') + ->from(_JOOM_TABLE_NAMESHIELDS) + ->where('npicid = '.$this->_id); + $this->_db->setQuery($query); + + $zindex = $this->_db->loadResult(); + if(!$zindex) + { + $zindex = 500; + } + else + { + $zindex--; + } + + $row = $this->getTable('joomgallerynameshields'); + $date = JFactory::getDate(); + + $row->npicid = $this->_id; + $row->nuserid = $userid; + $row->nxvalue = $xvalue; + $row->nyvalue = $yvalue; + $row->by = $by; + $row->nuserip = $_SERVER['REMOTE_ADDR']; + $row->ndate = $date->toSQL(); + $row->nzindex = $zindex; + + if(!$row->store()) + { + $this->setError(JText::_('COM_JOOMGALLERY_DETAIL_NAMETAGS_MSG_ERROR_SAVING')); + return false; + } + + $this->_mainframe->triggerEvent('onJoomAfterTag', array($row)); + + // Send messages + if($this->_config->get('jg_msg_nametag_type')) + { + $image = $this->getTable('joomgalleryimages'); + $image->load($this->_id); + + $user = JFactory::getUser($userid); + $name = $this->_config->get('jg_realname') ? $user->get('name') : $user->get('username'); + $by_name = $this->_config->get('jg_realname') ? $this->_user->get('name') : $this->_user->get('username'); + + require_once(JPATH_COMPONENT.'/helpers/messenger.php'); + $messenger = new JoomMessenger(); + + // General Message + if($by != $userid) + { + $subject = JText::sprintf('COM_JOOMGALLERY_MESSAGE_NEW_NAMETAG_OTHERS_BODY', $name, $by_name, $image->imgtitle, $this->_id); + } + else + { + $subject = JText::sprintf('COM_JOOMGALLERY_MESSAGE_NEW_NAMETAG_BODY', $name, $image->imgtitle, $this->_id); + } + $message = array( + 'from' => $by, + 'subject' => JText::_('COM_JOOMGALLERY_MESSAGE_NEW_NAMETAG_SUBJECT'), + 'body' => $subject, + 'mode' => 'nametag' + ); + + // Message to image owner + if($this->_config->get('jg_msg_nametag_toowner') && $by != $image->owner) + { + // Simply add the owner to the list of recipients + $message['recipient'] = $image->owner; + } + + // Send general message + $messenger->send($message); + + // Message to tagged user + if($this->_config->get('jg_msg_nametag_totaggeduser') && $by != $userid) + { + $url = JRoute::_('index.php?view=detail&id='.$this->_id, false).($this->_config->get('jg_anchors') ? '#joomimg' : ''); + + // Ensure that the correct host and path is prepended + $current_uri = JURI::getInstance(JURI::base()); + $current_host = $current_uri->toString(array('scheme', 'host', 'port')); + $uri = JFactory::getUri($url); + $uri->setHost($current_host); + $url = $uri->toString(); + + $message = array( + 'from' => $by, + 'recipient' => $userid, + 'subject' => JText::sprintf('COM_JOOMGALLERY_MESSAGE_YOU_WERE_TAGGED_SUBJECT', $this->_mainframe->getCfg('sitename')), + 'body' => JText::sprintf('COM_JOOMGALLERY_MESSAGE_YOU_WERE_TAGGED_BODY', $name, $image->imgtitle, $url), + 'type' => $messenger->getType('nametag') + ); + + $messenger->send($message); + } + } + + return true; + } + + /** + * Method to delete a name tag + * + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + public function remove() + { + if(!$userid = $this->_user->get('id')) + { + JError::raiseError(500, JText::_('COM_JOOMGALLERY_COMMON_PERMISSION_DENIED')); + } + + if(!$this->_config->get('jg_nameshields_others')) + { + + $query = $this->_db->getQuery(true) + ->delete(_JOOM_TABLE_NAMESHIELDS) + ->where('npicid = '.$this->_id) + ->where('nuserid = '.$userid); + $this->_db->setQuery($query); + + if(!$this->_db->query()) + { + $this->setError(JText::_('COM_JOOMGALLERY_DETAIL_NAMETAGS_MSG_ERROR_DELETING')); + return false; + } + } + else + { + $nid = JRequest::getInt('nid'); + + $row = $this->getTable('joomgallerynameshields'); + $row->load($nid); + if($row->nuserid == $userid || $row->by == $userid || $this->_user->authorise('core.manage', _JOOM_OPTION)) + { + if(!$row->delete()) + { + $this->setError(JText::_('COM_JOOMGALLERY_DETAIL_NAMETAGS_MSG_ERROR_DELETING')); + return false; + } + } + } + + return true; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/models/report.php b/deployed/joomgallery/components/com_joomgallery/models/report.php new file mode 100644 index 00000000..11b251e5 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/models/report.php @@ -0,0 +1,168 @@ +setError(JText::_('COM_JOOMGALLERY_COMMON_NO_IMAGE_SPECIFIED')); + + return false; + } + + // Do some security checks + if( !$this->_config->get('jg_report_images') + || (!$this->_config->get('jg_report_unreg') && !$this->_user->get('id')) + ) + { + $msg = JText::_('JERROR_ALERTNOAUTHOR'); + if(!$this->_user->get('id')) + { + $msg .= JText::_('COM_JOOMGALLERY_COMMON_MSG_YOU_ARE_NOT_LOGGED'); + } + + $this->setError($msg); + + return false; + } + + if(!$this->_user->get('id')) + { + $fromname = $this->_mainframe->getUserStateFromRequest('report.image.name', 'name', '', 'post'); + $from = $this->_mainframe->getUserStateFromRequest('report.image.email', 'email', '', 'post'); + } + else + { + $fromname = $this->_config->get('jg_realname') ? $this->_user->get('name') : $this->_user->get('username'); + $from = $this->_user->get('id'); + } + + $report = $this->_mainframe->getUserStateFromRequest('report.image.report', 'report', '', 'post'); + + if(!$report || !$fromname || !$from) + { + $this->setError(JText::_('COM_JOOMGALLERY_COMMON_MSG_FORM_NOT_FILLED')); + + return false; + } + + // Captcha + $valid = true; + $msg = ''; + $plugins = $this->_mainframe->triggerEvent('onJoomCheckCaptcha'); + foreach($plugins as $key => $result) + { + if(is_array($result) && isset($result['valid']) && !$result['valid']) + { + $valid = false; + if(isset($result['error']) && $result['error']) + { + $msg = $result['error']; + } + else + { + $msg = JText::_('COM_JOOMGALLERY_COMMON_MSG_SECURITY_CODE_WRONG'); + } + break; + } + } + + if(!$valid) + { + $this->setError($msg); + + return false; + } + + // Prepare links + $image = $this->_ambit->getImgObject($id); + $link = JRoute::_($redirect_url); + $img_src = JRoute::_($this->_ambit->getImg('img_url', $image)); + + $current_uri = JURI::getInstance(JURI::base()); + $current_host = $current_uri->toString(array('scheme', 'host', 'port')); + + // Ensure that the correct host and path is prepended + $uri = JFactory::getUri($link); + $uri->setHost($current_host); + $link = $uri->toString(); + $uri = JFactory::getUri($img_src); + $uri->setHost($current_host); + $img_src = $uri->toString(); + + $text = JText::sprintf( 'COM_JOOMGALLERY_REPORT_IMAGE_BODY', + $image->id, + $image->imgtitle, + $fromname, + $from, + $link, + $img_src, + $report + ); + + $subject = JText::sprintf('COM_JOOMGALLERY_REPORT_IMAGE_SUBJECT', $this->_mainframe->getCfg('sitename')); + + // Create the message + require_once JPATH_COMPONENT.'/helpers/messenger.php'; + $messenger = new JoomMessenger(); + + $message = array( 'from' => $from, + 'fromname' => $fromname, + 'subject' => $subject, + 'body' => $text, + 'mode' => 'report' + ); + + // Message to image owner + if($this->_config->get('jg_msg_report_toowner')) + { + $messenger->addRecipients($image->owner); + } + + // Send the message + if(!$messenger->send($message)) + { + $this->setError(JText::_('COM_JOOMGALLERY_COMMON_REPORT_NOT_SENT')); + + return false; + } + + // Delete data in session + $this->_mainframe->setUserState('report.image', null); + + $this->_mainframe->triggerEvent('onJoomAfterReport', array($message)); + + return true; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/models/search.php b/deployed/joomgallery/components/com_joomgallery/models/search.php new file mode 100644 index 00000000..6846e407 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/models/search.php @@ -0,0 +1,154 @@ +_loadSearchResults()) + { + return $this->_searchResults; + } + + return array(); + } + + /** + * Method to get the images searched for from the database + * + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + protected function _loadSearchResults() + { + if(empty($this->_searchResults)) + { + $sstring = JRequest::getString('sstring'); + $searchstring = $this->_db->escape(trim($sstring)); + + $categories = $this->_ambit->getCategoryStructure(); + $authorisedViewLevels = implode(',', $this->_user->getAuthorisedViewLevels()); + + // Create query object + $query = $this->_db->getQuery(true); + + // Create search part of the query + $where = '(u.username LIKE '.$this->_db->q('%'.$searchstring.'%').' + OR a.imgtitle LIKE '.$this->_db->q('%'.$searchstring.'%').' + OR LOWER(a.imgtext) LIKE '.$this->_db->q('%'.$searchstring.'%'); + + // Add query parts from plugins + $aliases = array('images' => 'a', 'categories' => 'ca'); + $plugins = $this->_mainframe->triggerEvent('onJoomSearch', array($searchstring, $aliases, _JOOM_OPTION.'.search')); + foreach($plugins as $plugin) + { + if(isset($plugin['images.select'])) + { + $query->select($plugin['images.select']); + } + if(isset($plugin['images.leftjoin'])) + { + $query->leftJoin($plugin['images.leftjoin']); + } + if(isset($plugin['images.where'])) + { + $query->where($plugin['images.where']); + } + if(isset($plugin['images.where.or'])) + { + $where .= ' + OR '.$plugin['images.where.or']; + } + } + + // Only now the search part can be finalized + $where .= ')'; + + // General select clause of the query + $query->select('a.*, '.JoomHelper::getSQLRatingClause('a').' AS rating, u.username, ca.cid, ca.name AS name'); + + // Count comments of each image if required + if($this->_config->get('jg_showcatcom')) + { + $subquery = $this->_db->getQuery(true) + ->select('COUNT(*)') + ->from(_JOOM_TABLE_COMMENTS) + ->where('cmtpic = a.id') + ->where('published = 1') + ->where('approved = 1'); + $query->select('('.$subquery.') As comments'); + } + + // Main part of the query + $query->from(_JOOM_TABLE_IMAGES.' AS a') + ->innerJoin(_JOOM_TABLE_CATEGORIES.' AS ca ON a.catid = ca.cid') + ->leftJoin('#__users AS u ON a.owner = u.id') + ->where($where) + ->where('a.published = 1') + ->where('a.approved = 1') + ->where('a.access IN ('.$authorisedViewLevels.')') + ->where('ca.published = 1') + ->where('ca.access IN ('.$authorisedViewLevels.')') + ->where('ca.cid IN ('.implode(',', array_keys($categories)).')') + ->where('a.hidden = 0') + ->where('ca.hidden = 0') + ->where('ca.in_hidden = 0') + ->where('ca.exclude_search = 0') + ->group('a.id') + ->order('a.id DESC'); + + $this->_db->setQuery($query); + + if(!$rows = $this->_db->loadObjectList()) + { + return false; + } + + $this->_searchResults = $rows; + } + + return true; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/models/send2friend.php b/deployed/joomgallery/components/com_joomgallery/models/send2friend.php new file mode 100644 index 00000000..b25a4195 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/models/send2friend.php @@ -0,0 +1,95 @@ +_user->get('id')) + { + $this->setError(JText::_('COM_JOOMGALLERY_COMMON_MSG_YOU_ARE_NOT_LOGGED')); + + return false; + } + + if(!$id) + { + $this->setError(JText::_('COM_JOOMGALLERY_COMMON_NO_IMAGE_SPECIFIED')); + + return false; + } + + require_once JPATH_COMPONENT.'/helpers/messenger.php'; + + $send2friendname = JRequest::getVar('send2friendname', '', 'post'); + $send2friendemail = JRequest::getVar('send2friendemail', '', 'post'); + + // Prepare link + $link = JRoute::_('index.php?view=detail&id='.$id); + + $current_uri = JURI::getInstance(JURI::base()); + $current_host = $current_uri->toString(array('scheme', 'host', 'port')); + + // Ensure that the correct host and path is prepended + $uri = JFactory::getUri($link); + $uri->setHost($current_host); + $link = $uri->toString(); + + $text = JText::sprintf( 'COM_JOOMGALLERY_MESSAGE_IMAGE_FROM_FRIEND_BODY', + $this->_config->get('jg_realname') ? $this->_user->get('name') : $this->_user->get('username'), + $this->_user->get('email'), + $link + ); + + $subject = $this->_mainframe->getCfg('sitename').' - '.JText::_('COM_JOOMGALLERY_MESSAGE_IMAGE_FROM_FRIEND_SUBJECT'); + + $message = array( 'from' => $this->_user->get('email'), + 'fromname' => $this->_config->get('jg_realname') ? $this->_user->get('name') : $this->_user->get('username'), + 'recipient' => $send2friendemail, + 'subject' => $subject, + 'body' => $text, + 'mode' => 'send2friend' + ); + + $messenger = new JoomMessenger(); + + if(!$messenger->send($message)) + { + $this->setError(JText::_('COM_JOOMGALLERY_DETAIL_SENDTOFRIEND_MSG_MAIL_NOT_SENT')); + + return false; + } + + $this->_mainframe->triggerEvent('onJoomAfterSend2Friend', array($message)); + + return true; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/models/toplist.php b/deployed/joomgallery/components/com_joomgallery/models/toplist.php new file mode 100644 index 00000000..915712a0 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/models/toplist.php @@ -0,0 +1,351 @@ +_loadLastCommented()) + { + return $this->_lastCommented; + } + + return array(); + } + + /** + * Method to load the last commented images from the database + * + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + protected function _loadLastCommented() + { + if(empty($this->_lastCommented)) + { + $rows = null; + $this->_mainframe->triggerEvent('onJoomGetLastComments', array(&$rows, $this->_config->get('jg_toplist'))); + + // If the data was not delivered by any plugin + if(!$rows) + { + $categories = $this->_ambit->getCategoryStructure(); + $authorisedViewLevels = implode(',', $this->_user->getAuthorisedViewLevels()); + + $query = $this->_db->getQuery(true) + ->select('a.*, cc.*, ca.*, a.owner AS owner, '.JoomHelper::getSQLRatingClause('a').' AS rating'); + if($this->_config->get('jg_showcatcom')) + { + $subquery = $this->_db->getQuery(true) + ->select('COUNT(*)') + ->from(_JOOM_TABLE_COMMENTS) + ->where('cmtpic = a.id') + ->where('published = 1') + ->where('approved = 1'); + $query->select('('.$subquery->__toString().') As comments'); + } + $query->from(_JOOM_TABLE_IMAGES.' AS a') + ->from(_JOOM_TABLE_CATEGORIES.' AS ca') + ->from(_JOOM_TABLE_COMMENTS.' AS cc') + ->where('a.id = cc.cmtpic') + ->where('a.catid = ca.cid') + ->where('a.published = 1') + ->where('a.approved = 1') + ->where('a.access IN ('.$authorisedViewLevels.')') + ->where('cc.published = 1') + ->where('cc.approved = 1') + ->where('ca.published = 1') + ->where('ca.access IN ('.$authorisedViewLevels.')') + ->where('ca.cid IN ('.implode(',', array_keys($categories)).')') + ->where('a.hidden = 0') + ->where('ca.hidden = 0') + ->where('ca.in_hidden = 0') + ->where('ca.exclude_toplists = 0') + ->order('cc.cmtdate DESC'); + + $this->_db->setQuery($query, 0, (int) $this->_config->get('jg_toplist')); + + if(!$rows = $this->_db->loadObjectList()) + { + return false; + } + } + + $this->_lastCommented = $rows; + } + + return true; + } + + /** + * Method to get the last added images + * + * @return object An object containing the last added images + * @since 1.5.5 + */ + public function getLastAdded() + { + if($this->_loadLastAdded()) + { + return $this->_lastAdded; + } + + return array(); + } + + /** + * Method to load the last added images from the database + * + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + protected function _loadLastAdded() + { + if(empty($this->_lastAdded)) + { + $categories = $this->_ambit->getCategoryStructure(); + $authorisedViewLevels = implode(',', $this->_user->getAuthorisedViewLevels()); + + $query = $this->_db->getQuery(true) + ->select('*, a.owner AS owner, '.JoomHelper::getSQLRatingClause('a').' AS rating'); + if($this->_config->get('jg_showcatcom')) + { + $subquery = $this->_db->getQuery(true) + ->select('COUNT(*)') + ->from(_JOOM_TABLE_COMMENTS) + ->where('cmtpic = a.id') + ->where('published = 1') + ->where('approved = 1'); + $query->select('('.$subquery->__toString().') As comments'); + } + $query->from(_JOOM_TABLE_IMAGES.' AS a') + ->from(_JOOM_TABLE_CATEGORIES.' AS ca') + ->where('a.catid = ca.cid') + ->where('a.published = 1') + ->where('a.approved = 1') + ->where('a.access IN ('.$authorisedViewLevels.')') + ->where('ca.published = 1') + ->where('ca.access IN ('.$authorisedViewLevels.')') + ->where('ca.cid IN ('.implode(',', array_keys($categories)).')') + ->where('a.hidden = 0') + ->where('ca.hidden = 0') + ->where('ca.in_hidden = 0') + ->where('ca.exclude_toplists = 0') + ->order('a.id DESC'); + + $this->_db->setQuery($query, 0, (int) $this->_config->get('jg_toplist')); + + if(!$rows = $this->_db->loadObjectList()) + { + return false; + } + + $this->_lastAdded = $rows; + } + + return true; + } + + /** + * Method to get the top rated images + * + * @return object An object containing the top rated images + * @since 1.5.5 + */ + public function getTopRated() + { + if($this->_loadTopRated()) + { + return $this->_topRated; + } + + return array(); + } + + /** + * Method to load the top rated images from the database + * + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + protected function _loadTopRated() + { + if(empty($this->_topRated)) + { + $categories = $this->_ambit->getCategoryStructure(); + $authorisedViewLevels = implode(',', $this->_user->getAuthorisedViewLevels()); + + $query = $this->_db->getQuery(true) + ->select('*, a.owner AS owner, '.JoomHelper::getSQLRatingClause('a').' AS rating'); + if($this->_config->get('jg_showcatcom')) + { + $subquery = $this->_db->getQuery(true) + ->select('COUNT(*)') + ->from(_JOOM_TABLE_COMMENTS) + ->where('cmtpic = a.id') + ->where('published = 1') + ->where('approved = 1'); + $query->select('('.$subquery->__toString().') As comments'); + } + $query->from(_JOOM_TABLE_IMAGES.' AS a') + ->from(_JOOM_TABLE_CATEGORIES.' AS ca') + ->where('a.catid = ca.cid') + ->where('a.imgvotes > 0') + ->where('a.published = 1') + ->where('a.approved = 1') + ->where('a.access IN ('.$authorisedViewLevels.')') + ->where('ca.published = 1') + ->where('ca.access IN ('.$authorisedViewLevels.')') + ->where('ca.cid IN ('.implode(',', array_keys($categories)).')') + ->where('a.hidden = 0') + ->where('ca.hidden = 0') + ->where('ca.in_hidden = 0') + ->where('ca.exclude_toplists = 0') + ->order('rating DESC, imgvotesum DESC'); + + $this->_db->setQuery($query, 0, (int) $this->_config->get('jg_toplist')); + + if(!$rows = $this->_db->loadObjectList()) + { + return false; + } + + $this->_topRated = $rows; + } + + return true; + } + + /** + * Method to get the most viewed images + * + * @return object An object containing the most viewed images + * @since 1.5.5 + */ + public function getMostViewed() + { + if($this->_loadMostViewed()) + { + return $this->_mostViewed; + } + + return array(); + } + + /** + * Method to load the most viewd images from the database + * + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + protected function _loadMostViewed() + { + if(empty($this->_mostViewed)) + { + $categories = $this->_ambit->getCategoryStructure(); + $authorisedViewLevels = implode(',', $this->_user->getAuthorisedViewLevels()); + + $query = $this->_db->getQuery(true) + ->select('*, a.owner AS owner, '.JoomHelper::getSQLRatingClause('a').' AS rating'); + if($this->_config->get('jg_showcatcom')) + { + $subquery = $this->_db->getQuery(true) + ->select('COUNT(*)') + ->from(_JOOM_TABLE_COMMENTS) + ->where('cmtpic = a.id') + ->where('published = 1') + ->where('approved = 1'); + $query->select('('.$subquery->__toString().') As comments'); + } + $query->from(_JOOM_TABLE_IMAGES.' AS a') + ->from(_JOOM_TABLE_CATEGORIES.' AS ca') + ->where('a.hits > 0') + ->where('a.catid = ca.cid') + ->where('a.published = 1') + ->where('a.approved = 1') + ->where('a.access IN ('.$authorisedViewLevels.')') + ->where('ca.published = 1') + ->where('ca.access IN ('.$authorisedViewLevels.')') + ->where('ca.cid IN ('.implode(',', array_keys($categories)).')') + ->where('a.hidden = 0') + ->where('ca.hidden = 0') + ->where('ca.in_hidden = 0') + ->where('ca.exclude_toplists = 0') + ->order('hits DESC'); + + $this->_db->setQuery($query, 0, (int) $this->_config->get('jg_toplist')); + + if(!$rows = $this->_db->loadObjectList()) + { + return false; + } + + $this->_mostViewed = $rows; + } + + return true; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/models/upload.php b/deployed/joomgallery/components/com_joomgallery/models/upload.php new file mode 100644 index 00000000..c9e028e0 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/models/upload.php @@ -0,0 +1,160 @@ +_db->getQuery(true) + ->select('COUNT(id)') + ->from(_JOOM_TABLE_IMAGES) + ->where('owner = '.$this->_user->get('id')); + + $timespan = $this->_config->get('jg_maxuserimage_timespan'); + if($timespan > 0) + { + $query->where('imgdate > (UTC_TIMESTAMP() - INTERVAL '. $timespan .' DAY)'); + } + + $this->_db->setQuery($query); + + return $this->_db->loadResult(); + } + + /** + * Returns the default user upload category + * + * @return int The default user upload category + * @since 3.0 + */ + public function getDefaultUserUploadCategory() + { + $defaultcat = 0; + + if($this->_config->get('jg_useruploaddefaultcat')) + { + $cats = $this->_ambit->getCategoryStructure(true); + + $newestcat = 0; + $oldestcat = PHP_INT_MAX; + $owncatsonly = $this->_config->get('jg_useruploaddefaultcat') > 2 ? true : false; + + foreach($cats as $cat) + { + if(!$owncatsonly || ($owncatsonly && $cat->owner == $this->_user->get('id'))) + { + if( ( $this->_user->authorise('joom.upload.inown', _JOOM_OPTION.'.category.'.$cat->cid) + && $cat->owner + && $cat->owner == $this->_user->get('id') + ) + || $this->_user->authorise('joom.upload', _JOOM_OPTION.'.category.'.$cat->cid) + ) + { + if($cat->cid > $newestcat) + { + $newestcat = $cat->cid; + } + if($cat->cid < $oldestcat) + { + $oldestcat = $cat->cid; + } + } + } + } + + switch($this->_config->get('jg_useruploaddefaultcat')) + { + case 1: + case 3: + if($oldestcat < PHP_INT_MAX) + { + $defaultcat = $oldestcat; + } + break; + case 2: + case 4: + if($newestcat) + { + $defaultcat = $newestcat; + } + break; + default: + break; + } + } + + return $defaultcat; + } + + /** + * Returns the redirect URL configured in configuration manager the user should be directed too + * after an successful image upload. + * + * @param string $uploadType Upload type (e.g. single, ajax, java, batch) + * @param string $defaultType Upload view to redirect too if no redirect url is configured, defaults to null + * @param boolean $xhtml Replace & by & for XML compilance. + * @return string The redirect URL + * @since 3.0 + */ + public function getRedirectUrlAfterUpload($uploadType = 'single', $defaultType = null, $xhtml = false) + { + $url = ''; + + // Set a redirect according to the correspondent setting in configuration manager + switch($this->_config->get('jg_redirect_after_upload')) + { + case 1: + $url = JRoute::_('index.php?view=upload&tab='.$uploadType, $xhtml); + break; + case 2: + $url = JRoute::_('index.php?view=userpanel', $xhtml); + break; + case 3: + $url = JRoute::_('index.php?view=gallery', $xhtml); + break; + default: + if(!empty($defaultType)) + { + $url = JRoute::_('index.php?view=upload&tab='.$defaultType, $xhtml); + } + break; + } + + return $url; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/models/usercategories.php b/deployed/joomgallery/components/com_joomgallery/models/usercategories.php new file mode 100644 index 00000000..c3962b4d --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/models/usercategories.php @@ -0,0 +1,359 @@ +filter_fields = array('c.cid', + 'c.name', + 'c.alias', + 'c.parent_id', + 'c.published', + 'c.access', + 'c.owner', + 'c.lft', + 'c.rgt', + 'c.level', + 'images' + ); + parent::__construct(); + } + + /** + * Retrieve the category data + * + * @return array Array of objects containing the category data + * @since 1.5.5 + */ + public function getCategories() + { + // Guests cannot own any categories + if(!$this->_user->get('id')) + { + return array(); + } + + if($this->_loadCategories()) + { + return $this->_categories; + } + + return array(); + } + + /** + * Method to get the total number of categories + * + * @return mixed The total number of categories or false + * @since 1.5.5 + */ + public function getTotal() + { + // Guests cannot own any categories + if(!$this->_user->get('id')) + { + return 0; + } + + // Let's load the data if it doesn't already exist + if(empty($this->_total)) + { + $query = $this->_buildQuery(); + try + { + $this->_total = $this->_getListCount($query); + } + catch(RuntimeException $e) + { + $this->setError($e->getMessage()); + return false; + } + } + + return $this->_total; + } + + /** + * Returns the number of categories that the current user owns + * + * @return int The number of categories of categories that the current user owns + * @since 2.1.6 + */ + public function getCategoryNumber() + { + if(empty($this->_categoryNumber)) + { + $query = $this->_db->getQuery(true); + $query->select('COUNT(cid)') + ->from(_JOOM_TABLE_CATEGORIES) + ->where('owner = '.$this->_user->get('id')); + $this->_db->setQuery($query); + $this->_categoryNumber = $this->_db->loadResult(); + } + + return $this->_categoryNumber; + } + + /** + * Method to get the starting number of items for the data set. + * + * @return int The starting number of items available in the data set. + * @since 3.0 + */ + public function getStart() + { + $start = $this->getState('list.start'); + $limit = $this->getState('list.limit'); + $total = $this->getTotal(); + if($start > $total - $limit) + { + $start = max(0, (int)(ceil($total / $limit) - 1) * $limit); + } + + return $start; + } + + /** + * Method to get the pagination object for the list. + * This method uses 'getTotal', 'getStart' and the current list limit of this view. + * + * @return object A pagination object + * @since 3.0 + */ + public function getPagination() + { + jimport('joomla.html.pagination'); + return new JPagination($this->getTotal(), $this->getStart(), $this->getState('list.limit')); + } + + /** + * Gets the value of a user state variable and sets it in the session + * This is the same as the method in JApplication except that this also can optionally + * force you back to the first page when a filter has changed + * + * @param string $key The key of the user state variable + * @param string $request The name of the variable passed in a request + * @param string $default The default value for the variable if not found (optional) + * @param string $type Filter for the variable, for valid values see {@link JFilterInput::clean()} (optional) + * @param boolean $resetPage If true, the limitstart in request is set to zero if the state has changed + * @return The requested user state + * @since 3.0 + */ + public function getUserStateFromRequest($key, $request, $default = null, $type = 'none', $resetPage = true) + { + $old_state = $this->_mainframe->getUserState($key); + $cur_state = (!is_null($old_state)) ? $old_state : $default; + $new_state = JRequest::getVar($request, null, 'default', $type); + + if($cur_state != $new_state && !is_null($new_state) && !is_null($old_state) && $resetPage) + { + JRequest::setVar('limitstart', 0); + } + + // Save the new value only if it was set in this request. + if($new_state !== null) + { + $this->_mainframe->setUserState($key, $new_state); + } + else + { + $new_state = $cur_state; + } + + return $new_state; + } + + /** + * Method to auto-populate the model state. + * + * This method should only be called once per instantiation and is designed + * to be called on the first call to the getState() method unless the model + * configuration flag to ignore the request is set. + * + * Note. Calling getState in this method will result in recursion. + * + * @param string $ordering An optional ordering field. + * @param string $direction An optional direction (asc|desc). + * + * @return void + * + * @since 3.0 + */ + protected function populateState($ordering = 'c.lft', $direction = 'asc') + { + $search = $this->getUserStateFromRequest('joom.usercategories.filter.search', 'filter_search'); + $this->setState('filter.search', $search); + + $published = $this->getUserStateFromRequest('joom.usercategories.filter.state', 'filter_state', ''); + $this->setState('filter.state', $published); + + $value = $this->getUserStateFromRequest('global.list.limit', 'limit', $this->_mainframe->getCfg('list_limit')); + $limit = $value; + $this->setState('list.limit', $limit); + + $value = $this->getUserStateFromRequest('joom.usercategories.limitstart', 'limitstart', 0); + $limitstart = ($limit != 0 ? (floor($value / $limit) * $limit) : 0); + $this->setState('list.start', $limitstart); + + // Check if the ordering field is in the white list, otherwise use the incoming value + $value = $this->getUserStateFromRequest('joom.usercategories.ordercol', 'filter_order', $ordering); + if(!in_array($value, $this->filter_fields)) + { + $value = $ordering; + $this->_mainframe->setUserState('joom.usercategories.ordercol', $value); + } + $this->setState('list.ordering', $value); + + // Check if the ordering direction is valid, otherwise use the incoming value + $value = $this->getUserStateFromRequest('joom.usercategories.orderdirn', 'filter_order_Dir', $direction); + if(!in_array(strtoupper($value), array('ASC', 'DESC', ''))) + { + $value = $direction; + $this->_mainframe->setUserState('joom.usercategories.orderdirn', $value); + } + $this->setState('list.direction', $value); + + if($search || $published) + { + $this->setState('filter.inuse', 1); + } + } + + /** + * Loads the categories data from the database + * + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + protected function _loadCategories() + { + // Let's load the data if it doesn't already exist + if(empty($this->_categories)) + { + $query = $this->_buildQuery(); + + if(!$rows = $this->_getList($query, $this->getState('list.start'), $this->getState('list.limit'))) + { + return false; + } + + $this->_categories = $rows; + } + + return true; + } + + /** + * Returns the query to get the category rows from the database + * + * @return string The query to be used to retrieve the category rows from the database + * @since 1.5.5 + */ + protected function _buildQuery() + { + $query = $this->_db->getQuery(true) + ->select('c.*') + ->select('(SELECT COUNT(cid) FROM '._JOOM_TABLE_CATEGORIES.' AS b WHERE b.parent_id = c.cid) AS children') + ->select('(SELECT COUNT(id) FROM '._JOOM_TABLE_IMAGES.' AS a WHERE a.catid = c.cid) AS images') + ->from(_JOOM_TABLE_CATEGORIES.' AS c') + ->where('parent_id > 0') + + // Join over the images for category thumbnail + ->select('i.id, i.catid, i.imgthumbname, i.hidden AS imghidden') + ->leftJoin(_JOOM_TABLE_IMAGES.' AS i ON ( c.thumbnail = i.id + AND i.published = 1 + AND i.approved = 1 + AND i.access IN ('.implode(',', $this->_user->getAuthorisedViewLevels()).'))'); + + // Filter by state + $filter = $this->getState('filter.state'); + + switch($filter) + { + case 1: + // Published + $query->where('c.published = 1'); + break; + case 2: + // Not published + $query->where('c.published = 0'); + break; + default: + // No filter by state + break; + } + + // Search + $search = $this->getState('filter.search'); + if(!empty($search)) + { + if(stripos($search, 'id:') === 0) + { + $query->where('c.cid = '.(int) substr($search, 3)); + } + else + { + $search = $this->_db->Quote('%'.$this->_db->escape($search, true).'%'); + $query->where('(c.name LIKE '.$search.' OR c.alias LIKE '.$search.' OR LOWER(description) LIKE '.$search.')'); + } + } + + + // A Super User will see all categories if the correspondent backend option is enabled + if(!$this->_config->get('jg_showallpicstoadmin') || !$this->_user->authorise('core.admin')) + { + $query->where('c.owner = '.$this->_user->get('id')); + } + + // Add the order clause + $query->order($this->_db->escape($this->getState('list.ordering', 'c.lft')).' '.$this->_db->escape($this->getState('list.direction', 'asc'))); + + return $query; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/models/userpanel.php b/deployed/joomgallery/components/com_joomgallery/models/userpanel.php new file mode 100644 index 00000000..f3ce3cee --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/models/userpanel.php @@ -0,0 +1,376 @@ +filter_fields = array( 'imgtitle', + 'ordering', + 'imgdate', + 'hits', + 'downloads', + 'published', + 'approved', + 'catid' + ); + parent::__construct(); + } + + /** + * Retrieves the images data + * + * @return array An array of images objects + * @since 1.5.5 + */ + public function getImages() + { + // Guests cannot own any images + if(!$this->_user->get('id')) + { + return array(); + } + + if($this->_loadImages()) + { + return $this->_images; + } + + return array(); + } + + /** + * Method to get the total number of images + * + * @return mixed The total number of images or false + * @since 1.5.5 + */ + public function getTotal() + { + // Guests cannot own any images + if(!$this->_user->get('id')) + { + return 0; + } + + // Let's load the data if it doesn't already exist + if(empty($this->_total)) + { + $query = $this->_buildQuery(); + try + { + $this->_total = $this->_getListCount($query); + } + catch(RuntimeException $e) + { + $this->setError($e->getMessage()); + return false; + } + } + + return $this->_total; + } + + /** + * Method to get the starting number of items for the data set. + * + * @return int The starting number of items available in the data set. + * @since 3.0 + */ + public function getStart() + { + $start = $this->getState('list.start'); + $limit = $this->getState('list.limit'); + $total = $this->getTotal(); + if($start > $total - $limit) + { + $start = max(0, (int)(ceil($total / $limit) - 1) * $limit); + } + + return $start; + } + + /** + * Method to get the pagination object for the list. + * This method uses 'getTotal', 'getStart' and the current list limit of this view. + * + * @return object A pagination object + * @since 3.0 + */ + public function getPagination() + { + jimport('joomla.html.pagination'); + return new JPagination($this->getTotal(), $this->getStart(), $this->getState('list.limit')); + } + + /** + * Retrieves the categories data from the database + * + * @return array An array of category IDs + * @since 1.5.5 + */ + public function getCategories() + { + // Let's load the data if it doesn't already exist + if(empty($this->_categories)) + { + $query = $this->_db->getQuery(true) + ->select('cid') + ->from(_JOOM_TABLE_CATEGORIES); + if(!$this->_config->get('jg_showallpicstoadmin') || !$this->_user->authorise('core.admin')) + { + $query->where('owner = '.$this->_user->get('id')); + } + + $this->_db->setQuery($query); + + $this->_categories = $this->_db->loadColumn(); + } + + return $this->_categories; + } + + /** + * Gets the value of a user state variable and sets it in the session + * This is the same as the method in JApplication except that this also can optionally + * force you back to the first page when a filter has changed + * + * @param string $key The key of the user state variable + * @param string $request The name of the variable passed in a request + * @param string $default The default value for the variable if not found (optional) + * @param string $type Filter for the variable, for valid values see {@link JFilterInput::clean()} (optional) + * @param boolean $resetPage If true, the limitstart in request is set to zero if the state has changed + * @return The requested user state + * @since 3.0 + */ + public function getUserStateFromRequest($key, $request, $default = null, $type = 'none', $resetPage = true) + { + $old_state = $this->_mainframe->getUserState($key); + $cur_state = (!is_null($old_state)) ? $old_state : $default; + $new_state = JRequest::getVar($request, null, 'default', $type); + + if($cur_state != $new_state && !is_null($new_state) && !is_null($old_state) && $resetPage) + { + JRequest::setVar('limitstart', 0); + } + + // Save the new value only if it was set in this request. + if($new_state !== null) + { + $this->_mainframe->setUserState($key, $new_state); + } + else + { + $new_state = $cur_state; + } + + return $new_state; + } + + /** + * Method to auto-populate the model state. + * + * This method should only be called once per instantiation and is designed + * to be called on the first call to the getState() method unless the model + * configuration flag to ignore the request is set. + * + * Note. Calling getState in this method will result in recursion. + * + * @param string $ordering An optional ordering field. + * @param string $direction An optional direction (asc|desc). + * + * @return void + * + * @since 3.0 + */ + protected function populateState($ordering = 'imgdate', $direction = 'desc') + { + $search = $this->getUserStateFromRequest('joom.userpanel.filter.search', 'filter_search', ''); + $this->setState('filter.search', $search); + + $published = $this->getUserStateFromRequest('joom.userpanel.filter.state', 'filter_state', ''); + $this->setState('filter.state', $published); + + $category = $this->getUserStateFromRequest('joom.userpanel.filter.category', 'filter_category', ''); + $this->setState('filter.category', $category); + + $value = $this->getUserStateFromRequest('global.list.limit', 'limit', $this->_mainframe->getCfg('list_limit')); + $limit = $value; + $this->setState('list.limit', $limit); + + $value = $this->getUserStateFromRequest('joom.userpanel.limitstart', 'limitstart', 0); + $limitstart = ($limit != 0 ? (floor($value / $limit) * $limit) : 0); + $this->setState('list.start', $limitstart); + + // Check if the ordering field is in the white list, otherwise use the incoming value + $value = $this->getUserStateFromRequest('joom.userpanel.ordercol', 'filter_order', $ordering); + if(!in_array($value, $this->filter_fields)) + { + $value = $ordering; + $this->_mainframe->setUserState('joom.userpanel.ordercol', $value); + } + $this->setState('list.ordering', $value); + + // Check if the ordering direction is valid, otherwise use the incoming value + $value = $this->getUserStateFromRequest('joom.userpanel.orderdirn', 'filter_order_Dir', $direction); + if(!in_array(strtoupper($value), array('ASC', 'DESC', ''))) + { + $value = $direction; + $this->_mainframe->setUserState('joom.userpanel.orderdirn', $value); + } + $this->setState('list.direction', $value); + + if($search || $published || $category) + { + $this->setState('filter.inuse', 1); + } + } + + /** + * Loads the images data from the database + * + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + protected function _loadImages() + { + // Let's load the data if it doesn't already exist + if(empty($this->_images)) + { + jimport('joomla.filesystem.file'); + + $query = $this->_buildQuery(); + + if(!$rows = $this->_getList($query, $this->getState('list.start'), $this->getState('list.limit'))) + { + return false; + } + + $this->_images = $rows; + } + + return true; + } + + /** + * Returns the query to get the images rows from the database + * + * @return string The query to get the image rows from the database + * @since 1.5.5 + */ + protected function _buildQuery() + { + $query = $this->_db->getQuery(true) + ->select('*') + ->from(_JOOM_TABLE_IMAGES); + + // Filter by state + $filter = $this->getState('filter.state'); + switch($filter) + { + case 1: + // Approved + $query->where('approved = 1'); + break; + case 2: + // Not yet approved / rejected + $query->where('(approved = 0 OR approved = -1)'); + break; + case 3: + // Published + $query->where('published = 1'); + break; + case 4: + // Not published + $query->where('published = 0'); + break; + default: + // No filter by state + break; + } + + // Filter by category + $catid = $this->getState('filter.category'); + if(!empty($catid)) + { + $query->where('catid = '.$catid); + } + + // A Super User will see all images if the correspondent backend option is enabled + if(!$this->_config->get('jg_showallpicstoadmin') || !$this->_user->authorise('core.admin')) + { + $query->where('owner = '.$this->_user->get('id')); + } + + // Search + $search = $this->getState('filter.search'); + if(!empty($search)) + { + if(stripos($search, 'id:') === 0) + { + $query->where('id = '.(int) substr($search, 3)); + } + else + { + $search = $this->_db->Quote('%'.$this->_db->escape($search, true).'%'); + $query->where('(imgtitle LIKE '.$search.' OR alias LIKE '.$search.' OR LOWER(imgtext) LIKE '.$search.')'); + } + } + + // Add the order clause + $orderCol = $this->state->get('list.ordering'); + $orderDirn = $this->state->get('list.direction'); + if($orderCol == 'ordering' || $orderCol == 'catid') + { + $orderCol = 'catid '.$orderDirn.', ordering'; + } + $query->order($this->_db->escape($orderCol.' '.$orderDirn)); + + return $query; + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/models/vote.php b/deployed/joomgallery/components/com_joomgallery/models/vote.php new file mode 100644 index 00000000..e2d3fa8d --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/models/vote.php @@ -0,0 +1,232 @@ +setId($id); + } + + /** + * Method to set the image I + * + * @param int $id The image ID + * @since 1.5.5 + */ + public function setId($id) + { + // Set new image ID if valid + if(!$id) + { + $this->_mainframe->redirect(JRoute::_('index.php?view=gallery', false), JText::_('COM_JOOMGALLERY_COMMON_NO_IMAGE_SPECIFIED'), 'notice'); + } + $this->_id = $id; + } + + /** + * Method to get the image ID + * + * @return int The image ID + * @since 1.5.5 + */ + public function getId() + { + return $this->_id; + } + + /** + * Method to vote an image + * + * @return boolean True on success, false otherwise + * @since 1.5.5 + */ + public function vote() + { + // Check for hacking attempt + $categories = $this->_ambit->getCategoryStructure(); + $query = $this->_db->getQuery(true) + ->select('a.owner') + ->from(_JOOM_TABLE_IMAGES.' AS a') + ->leftJoin(_JOOM_TABLE_CATEGORIES.' AS c ON c.cid = a.catid') + ->where('a.published = 1') + ->where('a.approved = 1') + ->where('a.id = '.$this->_id) + ->where('a.access IN ('.implode(',', $this->_user->getAuthorisedViewLevels()).')') + ->where('c.cid IN ('.implode(',', array_keys($categories)).')'); + $this->_db->setQuery($query); + $owner = $this->_db->loadResult(); + if(is_null($owner) || ($this->_config->get('jg_votingonlyreg') && !$this->_user->get('id'))) + { + $this->setError('Stop Hacking attempt!'); + + return false; + } + + // No votes from image owner allowed + if($this->_config->get('jg_votingonlyreg') && $this->_user->get('id') == $owner) + { + $this->setError(JText::_('COM_JOOMGALLERY_DETAIL_RATING_NOT_ON_OWN_IMAGES')); + + return false; + } + + $vote = JRequest::getInt('imgvote'); + + // Check if vote was manipulated with modifying the HTML code + if($vote < 1 || $vote > $this->_config->get('jg_maxvoting')) + { + $this->setError('Stop Hacking attempt!'); + + return false; + } + + // Get voted or not + if($this->_config->get('jg_votingonlyreg')) + { + // Check whether the user already voted on that image + $query->clear() + ->select('COUNT(*)') + ->from(_JOOM_TABLE_VOTES) + ->where('userid = '.$this->_user->get('id')) + ->where('picid = '.$this->_id); + $this->_db->setQuery($query); + + // Vote or enqueue notice + if($this->_db->loadResult()) + { + $this->setError(JText::_('COM_JOOMGALLERY_DETAIL_RATINGS_MSG_YOUR_VOTE_NOT_COUNTED')); + + return false; + } + } + else + { + if($this->_config->get('jg_votingonlyonce')) + { + // Check whether there was already a vote for that image + // from the same IP address during the last 24 hours + $query->clear() + ->select('COUNT(*)') + ->from(_JOOM_TABLE_VOTES) + ->where('userip = '.$this->_db->q($_SERVER['REMOTE_ADDR'])) + ->where('picid = '.$this->_id) + ->where('datevoted > DATE_SUB(NOW(), INTERVAL 24 HOUR)'); + $this->_db->setQuery($query); + + // Vote or enqueue notice + if($this->_db->loadResult()) + { + $this->setError(JText::_('COM_JOOMGALLERY_DETAIL_RATINGS_MSG_YOUR_VOTE_NOT_COUNTED')); + + return false; + } + } + } + + // Get old values from database + $query->clear() + ->select('imgvotes, imgvotesum') + ->from(_JOOM_TABLE_IMAGES) + ->where('id = '.$this->_id); + $this->_db->setQuery($query); + $row = $this->_db->loadObject(); + + // Recalculate with the new vote + $row->imgvotes++; + $row->imgvotesum = $row->imgvotesum + $vote; + + // Trigger event 'onJoomBeforeVote' + $plugins = $this->_mainframe->triggerEvent('onJoomBeforeVote', array(&$row, $vote)); + if(in_array(false, $plugins, true)) + { + return false; + } + + // Save new values + $query->clear() + ->update(_JOOM_TABLE_IMAGES) + ->set('imgvotes = '.$row->imgvotes) + ->set('imgvotesum = '.$row->imgvotesum) + ->where('id = '.$this->_id); + $this->_db->setQuery($query); + if(!$this->_db->query()) + { + $this->setError($this->_db->getErrorMsg()); + + return false; + } + + // Store log of vote + $row = $this->getTable('joomgalleryvotes'); + $date = JFactory::getDate(); + + $row->picid = $this->_id; + $row->userid = $this->_user->get('id'); + $row->userip = $_SERVER['REMOTE_ADDR']; + $row->datevoted = $date->toSQL(); + $row->vote = $vote; + + if(!$row->store()) + { + $this->setError($row->getError()); + + return false; + } + + $this->_mainframe->triggerEvent('onJoomAfterVote', array($row, $vote)); + + return true; + } + + /** + * Get new rating for the image voted to refresh detail view + * + * @return object Holds the image rating data + * @since 2.1 + */ + public function getRating() + { + $query = $this->_db->getQuery(true) + ->select('imgvotes, imgvotesum, '.JoomHelper::getSQLRatingClause().' AS rating') + ->from(_JOOM_TABLE_IMAGES) + ->where('id = '.$this->_id); + $this->_db->setQuery($query); + + return $this->_db->loadObject(); + } +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/router.php b/deployed/joomgallery/components/com_joomgallery/router.php new file mode 100644 index 00000000..28a6b337 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/router.php @@ -0,0 +1,532 @@ +getQuery(true) + ->select('alias') + ->from(_JOOM_TABLE_IMAGES) + ->where('id = '.(int) $query['id']); + $db->setQuery($dbquery); + if(!$segment = $db->loadResult()) + { + // Append ID of image if alias was not found? + $segment = 'alias-not-found-'.$query['id']; + } + $segments[] = $segment; + unset($query['view']); + unset($query['id']); + } + + if(isset($query['view']) && $query['view'] == 'editcategory') + { + if(isset($query['catid'])) + { + $segments[] = 'editcategory'; + + $dbquery = $db->getQuery(true) + ->select('alias') + ->from(_JOOM_TABLE_CATEGORIES) + ->where('cid = '.(int) $query['catid']); + $db->setQuery($dbquery); + if(!$segment = $db->loadResult()) + { + // Append ID of category if alias was not found + $segment = 'alias-not-found-'.$query['catid']; + } + $segments[] = $segment; + } + else + { + $segments[] = 'newcategory'; + } + unset($query['view']); + unset($query['catid']); + } + + if(isset($query['view']) && $query['view'] == 'gallery') + { + unset($query['view']); + + JLoader::register('JoomRouting', JPATH_ROOT.'/components/'._JOOM_OPTION.'/helpers/routing.php'); + if(isset($query['Itemid']) && $Itemid = JoomRouting::checkItemid($query['Itemid'])) + { + $query['Itemid'] = $Itemid; + } + } + + if(isset($query['view']) && $query['view'] == 'image') + { + $sef_image = JComponentHelper::getParams(_JOOM_OPTION)->get('sef_image', 0); + if(!$sef_image) + { + $segments[] = 'image'; + + return $segments; + } + + unset($query['view']); + $query['format'] = 'jpg'; + $segment = 'image-'.$query['id']; + if(isset($query['type'])) + { + $segment .= '-'.$query['type']; + unset($query['type']); + } + else + { + $segment .= '-thumb'; + } + if(isset($query['width']) && isset($query['height'])) + { + $segment .= '-'.$query['width'].'-'.$query['height']; + unset($query['width']); + unset($query['height']); + + if(isset($query['pos'])) + { + $segment .= '-'.$query['pos']; + } + + if(isset($query['x'])) + { + if(!isset($query['pos'])) + { + $segment .= '-0'; + } + + $segment .= '-'.$query['x']; + } + + if(isset($query['y'])) + { + if(!isset($query['pos'])) + { + $segment .= '-0'; + } + else + { + unset($query['pos']); + } + + if(!isset($query['x'])) + { + $segment .= '-0'; + } + else + { + unset($query['x']); + } + + $segment .= '-'.$query['y']; + + unset($query['y']); + } + else + { + if(isset($query['pos'])) + { + unset($query['pos']); + } + if(isset($query['x'])) + { + unset($query['x']); + } + } + } + + $segments[] = $segment; + + if($sef_image == 1) + { + unset($query['id']); + + return $segments; + } + + //if($config->get('jg_image_sef') == 2) + //{ + $dbquery = $db->getQuery(true) + ->select('alias') + ->from(_JOOM_TABLE_IMAGES) + ->where('id = '.(int) $query['id']); + $db->setQuery($dbquery); + if($segment = $db->loadResult()) + { + $segments[] = $segment; + } + //} + + unset($query['id']); + } + if(isset($query['view']) && $query['view'] == 'mini') + { + $segments[] = 'mini'; + unset($query['view']); + } + if(isset($query['view']) && $query['view'] == 'search') + { + $segments[] = 'search'; + unset($query['view']); + } + if(isset($query['view']) && $query['view'] == 'upload') + { + $segments[] = 'upload'; + unset($query['view']); + } + if(isset($query['view']) && $query['view'] == 'usercategories') + { + $segments[] = 'usercategories'; + unset($query['view']); + } + if(isset($query['view']) && $query['view'] == 'userpanel') + { + $segments[] = 'userpanel'; + unset($query['view']); + } + + if(isset($query['view']) && $query['view'] == 'favourites') + { + $segments[] = 'favourites'; + + unset($query['view']); + + if(isset($query['layout'])) + { + if($query['layout'] == 'default') + { + unset($query['layout']); + } + } + } + + if(isset($query['view']) and $query['view'] == 'category') + { + $dbquery = $db->getQuery(true) + ->select('alias') + ->from(_JOOM_TABLE_CATEGORIES) + ->where('cid = '.(int) $query['catid']); + $db->setQuery($dbquery); + if(!$segment = $db->loadResult()) + { + // Append ID of category if alias was not found + $segment = 'alias-not-found-'.$query['catid']; + } + $segments[] = $segment; + unset($query['catid']); + unset($query['view']); + } + + if(isset($query['id']) && isset($query['view']) && $query['view'] == 'detail') + { + $dbquery = $db->getQuery(true) + ->select('catid, alias') + ->from(_JOOM_TABLE_IMAGES) + ->where('id = '.(int) $query['id']); + $db->setQuery($dbquery); + $result_array = $db->loadAssoc(); + $dbquery->clear() + ->select('alias') + ->from(_JOOM_TABLE_CATEGORIES) + ->where('cid = '.$result_array['catid']); + $db->setQuery($dbquery); + if(!$segment = $db->loadResult()) + { + // Append ID of category if alias was not found + $segment = 'alias-not-found-'.$result_array['catid']; + } + $segments[] = $segment; + if(!$segment = $result_array['alias']) + { + // Append ID of image if alias was not found + $segment = 'alias-not-found-'.$query['id']; + } + $segments[] = $segment; + unset($query['id']); + unset($query['view']); + } + + if(isset($query['task']) && $query['task'] == 'savecategory') + { + $segments[] = 'savecategory'; + unset($query['task']); + } + + if(isset($query['task']) && $query['task'] == 'deletecategory') + { + $segments[] = 'deletecategory'; + unset($query['task']); + } + + return $segments; +} + +/** + * Analyses a SEF URL to retreive the parameters for JoomGallery + * + * @param array $segments An array containing the segments of the SEF URL + * @return array An array of the parameters retreived + * @since 1.5.5 + */ +function JoomGalleryParseRoute($segments) +{ + require_once JPATH_ADMINISTRATOR.'/components/com_joomgallery/includes/defines.php'; + JLoader::register('JoomRouting', JPATH_ROOT.'/components/'._JOOM_OPTION.'/helpers/routing.php'); + + $vars = array(); + + $language = JFactory::getLanguage(); + $language->load('com_joomgallery'); + + if( $segments[0] == str_replace('-', ':', JApplication::stringURLSafe(JText::_('COM_JOOMGALLERY_COMMON_TOPLIST_TOP_RATED'))) + || $segments[0] == str_replace('-', ':', JApplication::stringURLSafe(JText::_('COM_JOOMGALLERY_COMMON_TOPLIST_LAST_ADDED'))) + || $segments[0] == str_replace('-', ':', JApplication::stringURLSafe(JText::_('COM_JOOMGALLERY_COMMON_TOPLIST_LAST_COMMENTED'))) + || $segments[0] == str_replace('-', ':', JApplication::stringURLSafe(JText::_('COM_JOOMGALLERY_COMMON_TOPLIST_MOST_VIEWED'))) + || $segments[0] == str_replace('-', ':', 'top-rated') + || $segments[0] == str_replace('-', ':', 'last-added') + || $segments[0] == str_replace('-', ':', 'last-commented') + || $segments[0] == str_replace('-', ':', 'most-viewed') + ) + { + $vars['view'] = 'toplist'; + + switch($segments[0]) + { + case str_replace('-', ':', 'top-rated'): + case str_replace('-', ':', JApplication::stringURLSafe(JText::_('COM_JOOMGALLERY_COMMON_TOPLIST_TOP_RATED'))): + $vars['type'] = 'toprated'; + break; + case str_replace('-', ':', 'last-added'): + case str_replace('-', ':', JApplication::stringURLSafe(JText::_('COM_JOOMGALLERY_COMMON_TOPLIST_LAST_ADDED'))): + $vars['type'] = 'lastadded'; + break; + case str_replace('-', ':', 'last-commented'): + case str_replace('-', ':', JApplication::stringURLSafe(JText::_('COM_JOOMGALLERY_COMMON_TOPLIST_LAST_COMMENTED'))): + $vars['type'] = 'lastcommented'; + break; + default: + break; + } + + return $vars; + } + + if($segments[0] == 'newcategory') + { + $vars['view'] = 'editcategory'; + return $vars; + } + + if($segments[0] == 'editcategory') + { + array_shift($segments); + if($result_array = JoomRouting::getId($segments)) + { + $vars['catid'] = $result_array['id']; + } + $vars['view'] = 'editcategory'; + + return $vars; + } + + if($segments[0] == 'edit') + { + array_shift($segments); + if(count($segments) && $result_array = JoomRouting::getId($segments)) + { + $vars['id'] = $result_array['id']; + $vars['view'] = 'edit'; + } + else + { + $vars['view'] = 'upload'; + } + + return $vars; + } + + if($segments[0] == 'savecategory') + { + $vars['task'] = 'savecategory'; + + return $vars; + } + + if($segments[0] == 'deletecategory') + { + $vars['task'] = 'deletecategory'; + + return $vars; + } + + if(strpos($segments[0], 'image') === 0) + { + $vars['view'] = 'image'; + $vars['format'] = 'raw'; + $exploded = explode('-', str_replace(':', '-', $segments[0])); + if(isset($exploded[1])) + { + $vars['id'] = $exploded[1]; + } + if(isset($exploded[2])) + { + $vars['type'] = $exploded[2]; + } + if(isset($exploded[3])) + { + $vars['width'] = $exploded[3]; + } + if(isset($exploded[4])) + { + $vars['height'] = $exploded[4]; + } + if(isset($exploded[5])) + { + $vars['pos'] = $exploded[5]; + } + if(isset($exploded[6])) + { + $vars['x'] = $exploded[6]; + } + if(isset($exploded[7])) + { + $vars['y'] = $exploded[7]; + } + + return $vars; + } + + if($result_array = JoomRouting::getId($segments)) + { + if($result_array['view'] == 'category') + { + $vars['view'] = 'category'; + $vars['catid'] = $result_array['id']; + } + else + { + $vars['view'] = 'detail'; + $vars['id'] = $result_array['id']; + } + + return $vars; + } + + $valid_views = array( 'downloadzip', + 'favourites', + 'mini', + 'search', + 'upload', + 'usercategories', + 'userpanel' + ); + if(in_array($segments[0], $valid_views)) + { + $vars['view'] = $segments[0]; + return $vars; + } + + $vars['view'] = 'gallery'; + + return $vars; +} \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/view.php b/deployed/joomgallery/components/com_joomgallery/view.php new file mode 100644 index 00000000..4022afe0 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/view.php @@ -0,0 +1,207 @@ +_ambit = JoomAmbit::getInstance(); + $this->_config = JoomConfig::getInstance(); + + $this->_mainframe = JFactory::getApplication('site'); + $this->_user = JFactory::getUser(); + $this->_doc = JFactory::getDocument(); + + JHtml::addIncludePath(JPATH_COMPONENT_ADMINISTRATOR.'/helpers/html'); + + // If we are just displaying an image we don't need anything else + if(JRequest::getCmd('format') == 'raw' || JRequest::getCmd('format') == 'jpg' || JRequest::getCmd('format') == 'json' || JRequest::getCmd('format') == 'feed') + { + return; + } + + // Add the CSS file generated from backend settings + $this->_doc->addStyleSheet($this->_ambit->getStyleSheet($this->_config->getStyleSheetName())); + + // Add the main CSS file + $this->_doc->addStyleSheet($this->_ambit->getStyleSheet('joomgallery.css')); + + // Add the RTL CSS file if an RTL language is used + if(JFactory::getLanguage()->isRTL()) + { + $this->_doc->addStyleSheet($this->_ambit->getStyleSheet('joomgallery_rtl.css')); + } + + // Add individual CSS file if it exists + if(file_exists(JPATH_ROOT.'/media/joomgallery/css/joom_local.css')) + { + $this->_doc->addStyleSheet($this->_ambit->getStyleSheet('joom_local.css')); + } + + $pngbehaviour = " " + . "\n" + ." " + . "\n" + . " "; + $this->_doc->addCustomTag($pngbehaviour); + + // Set documents meta data taken from menu entry definition + $params = $this->_mainframe->getParams(); + if($params->get('menu-meta_description')) + { + $this->_doc->setDescription($params->get('menu-meta_description')); + } + if($params->get('menu-meta_keywords')) + { + $this->_doc->setMetadata('keywords', $params->get('menu-meta_keywords')); + } + if($params->get('robots')) + { + $this->_doc->setMetadata('robots', $params->get('robots')); + } + + // Page title + $pagetitle = JoomHelper::addSitenameToPagetitle($this->_doc->getTitle()); + $this->_doc->setTitle($pagetitle); + + // Check for alternative layout only if this is not the active menu item + $active = $this->_mainframe->getMenu()->getActive(); + if(!$active || strpos($active->link, 'view='.$this->getName()) === false) + { + // Get the default layout from the configuration + if($layout = $this->_config->get('jg_alternative_layout')) + { + $this->setLayout($layout); + } + } + } + + /** + * HTML view display method + * + * @param string $tpl The name of the template file to parse + * @return void + * @since 1.5.5 + */ + public function display($tpl = null) + { + $layout = $this->getLayout(); + if($layout != 'default' && ($layout != 'list' || JRequest::getCmd('view') != 'favourites')) + { + JFactory::getLanguage()->load('com_joomgallery.layout.'.$layout); + + $this->_ambit->set('layout', $layout); + + if(is_file(JPATH_ROOT.'/media/joomgallery/css/'.$layout.'.css')) + { + $this->_doc->addStyleSheet($this->_ambit->getStyleSheet($layout.'.css')); + } + } + + parent::display($tpl = null); + } + + /** + * Returns all found modules published at the given position + * + * @param string $pos The name of the module position to load + * @return string The HTML output of the modules for displaying them + * @since 1.5.5 + */ + public function loadModules($pos) + { + $html = ''; + + $modules = JoomHelper::getRenderedModules($pos); + if(count($modules)) + { + ob_start(); + foreach($modules as $module): ?> +
    +showtitle): ?> +
    +

    + title; ?>  +

    +
    +rendered; ?> +
    + \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/views/category/metadata.xml b/deployed/joomgallery/components/com_joomgallery/views/category/metadata.xml new file mode 100644 index 00000000..2b5b44fe --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/views/category/metadata.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/views/category/tmpl/default.php b/deployed/joomgallery/components/com_joomgallery/views/category/tmpl/default.php new file mode 100644 index 00000000..08d08f3a --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/views/category/tmpl/default.php @@ -0,0 +1,14 @@ +loadTemplate('header'); + +if(count($this->categories)): + echo $this->loadTemplate('subcategories'); +endif; + +if(count($this->images)): + echo $this->loadTemplate('head'); + echo $this->loadTemplate('images'); +endif; + +echo $this->loadTemplate('footer'); \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/views/category/tmpl/default.xml b/deployed/joomgallery/components/com_joomgallery/views/category/tmpl/default.xml new file mode 100644 index 00000000..6f457108 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/views/category/tmpl/default.xml @@ -0,0 +1,35 @@ + + + + + + + + +
    + +
    +
    + +
    + + + + +
    +
    +
    \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/views/category/tmpl/default_footer.php b/deployed/joomgallery/components/com_joomgallery/views/category/tmpl/default_footer.php new file mode 100644 index 00000000..d467e2e9 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/views/category/tmpl/default_footer.php @@ -0,0 +1,69 @@ + +params->get('show_footer_separator')): ?> + +params->get('show_footer_toplist', 0)): ?> +
    + +
    +params->get('show_rmsm_legend', 0)): ?> +
    +
    + +
    +
    +params->get('show_footer_allpics', 0) OR $this->params->get('show_footer_allhits', 0)): ?> +
    +params->get('show_footer_allpics', 0)): ?> + numberofpics); ?> +params->get('show_footer_allhits', 0)): ?> +
    +params->get('show_footer_allhits', 0)): ?> + numberofhits); ?> + +
    +params->get('show_footer_backlink')): ?> + +params->get('show_footer_search', 0)): ?> + +params->get('show_footer_pathway', 0)): ?> +
    + + + pathway; ?> +
    +params->get('show_btm_modules', 0)): ?> +
    +modules['btm'] as $module): ?> +
    + rendered; ?> +
    + +
    +params->get('show_credits', 0)): ?> +
    +
    + + Powered by JoomGallery + +
    + +
    \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/views/category/tmpl/default_head.php b/deployed/joomgallery/components/com_joomgallery/views/category/tmpl/default_head.php new file mode 100644 index 00000000..e1a973d0 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/views/category/tmpl/default_head.php @@ -0,0 +1,84 @@ + +
    +_config->get('jg_showcathead')): ?> +
    +params->get('show_feed_icon')): ?> +
    + > + + +
    +params->set('show_feed_icon', 0); + endif; + if($this->params->get('show_headerfavourites_icon')): ?> +
    +params->get('show_headerfavourites_icon') == 1): ?> + > + +params->get('show_headerfavourites_icon') == 2): ?> + > + +params->get('show_headerfavourites_icon') == -1): ?> + > + + +params->get('show_headerfavourites_icon') == -2): ?> + > + + + +
    +params->get('show_upload_icon')): ?> +
    + + + +
    +params->set('show_upload_icon', 0); + endif; ?> + category->name; ?> +
    +_config->get('jg_showcatdescriptionincat') == 1): ?> +
    + category->description); ?> +
    +_config->get('jg_usercatorder')): ?> +
    +
    + + +order_by != 'title' && $this->order_by != 'hits' && $this->order_by != 'date' && $this->order_by != 'user' && $this->order_by != 'rating'): + $disabled = ' disabled="disabled"'; + endif; ?> + title="orderdir" name="orderdir" onchange="this.form.submit()" class="inputbox"> + + + + +
    + +
    diff --git a/deployed/joomgallery/components/com_joomgallery/views/category/tmpl/default_header.php b/deployed/joomgallery/components/com_joomgallery/views/category/tmpl/default_header.php new file mode 100644 index 00000000..21ec57d7 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/views/category/tmpl/default_header.php @@ -0,0 +1,101 @@ + + \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/views/detail/tmpl/default_header.php b/deployed/joomgallery/components/com_joomgallery/views/detail/tmpl/default_header.php new file mode 100644 index 00000000..21ec57d7 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/views/detail/tmpl/default_header.php @@ -0,0 +1,101 @@ + + \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/views/downloadzip/tmpl/default_header.php b/deployed/joomgallery/components/com_joomgallery/views/downloadzip/tmpl/default_header.php new file mode 100644 index 00000000..21ec57d7 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/views/downloadzip/tmpl/default_header.php @@ -0,0 +1,101 @@ + + \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/views/edit/tmpl/default_header.php b/deployed/joomgallery/components/com_joomgallery/views/edit/tmpl/default_header.php new file mode 100644 index 00000000..21ec57d7 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/views/edit/tmpl/default_header.php @@ -0,0 +1,101 @@ + + \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/views/editcategory/tmpl/default_header.php b/deployed/joomgallery/components/com_joomgallery/views/editcategory/tmpl/default_header.php new file mode 100644 index 00000000..21ec57d7 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/views/editcategory/tmpl/default_header.php @@ -0,0 +1,101 @@ + + \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/views/favourites/tmpl/default_header.php b/deployed/joomgallery/components/com_joomgallery/views/favourites/tmpl/default_header.php new file mode 100644 index 00000000..21ec57d7 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/views/favourites/tmpl/default_header.php @@ -0,0 +1,101 @@ + + \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/views/favourites/tmpl/list_header.php b/deployed/joomgallery/components/com_joomgallery/views/favourites/tmpl/list_header.php new file mode 100644 index 00000000..656d5534 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/views/favourites/tmpl/list_header.php @@ -0,0 +1,101 @@ + + \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/views/gallery/tmpl/default_header.php b/deployed/joomgallery/components/com_joomgallery/views/gallery/tmpl/default_header.php new file mode 100644 index 00000000..21ec57d7 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/views/gallery/tmpl/default_header.php @@ -0,0 +1,101 @@ + + \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/views/search/tmpl/default_header.php b/deployed/joomgallery/components/com_joomgallery/views/search/tmpl/default_header.php new file mode 100644 index 00000000..21ec57d7 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/views/search/tmpl/default_header.php @@ -0,0 +1,101 @@ + + \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/views/toplist/tmpl/default_header.php b/deployed/joomgallery/components/com_joomgallery/views/toplist/tmpl/default_header.php new file mode 100644 index 00000000..21ec57d7 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/views/toplist/tmpl/default_header.php @@ -0,0 +1,101 @@ + + \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/views/upload/tmpl/default_header.php b/deployed/joomgallery/components/com_joomgallery/views/upload/tmpl/default_header.php new file mode 100644 index 00000000..21ec57d7 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/views/upload/tmpl/default_header.php @@ -0,0 +1,101 @@ + + \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/views/usercategories/tmpl/default_header.php b/deployed/joomgallery/components/com_joomgallery/views/usercategories/tmpl/default_header.php new file mode 100644 index 00000000..21ec57d7 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/views/usercategories/tmpl/default_header.php @@ -0,0 +1,101 @@ + + \ No newline at end of file diff --git a/deployed/joomgallery/components/com_joomgallery/views/userpanel/tmpl/default_header.php b/deployed/joomgallery/components/com_joomgallery/views/userpanel/tmpl/default_header.php new file mode 100644 index 00000000..21ec57d7 --- /dev/null +++ b/deployed/joomgallery/components/com_joomgallery/views/userpanel/tmpl/default_header.php @@ -0,0 +1,101 @@ + +\n'; + if (node._hc) { + str += '
    \n'; + str += this.addNode(node); + str += '
    \n'; + } + this.aIndent.pop(); + return str; +}; + +// Adds the empty and line icons +jg_dTree.prototype.indent = function(node, nodeId) { + var str = ''; + if (this.root.id != node.pid) { + for (var n=0; n'; + (node._ls) ? this.aIndent.push(0) : this.aIndent.push(1); + if (node._hc) { + str += ''; + } else str += ''; + } + return str; +}; + +// Checks if a node has any children and if it is the last sibling +jg_dTree.prototype.setCS = function(node) { + var lastId; + for (var n=0; n
    '}); + } + } + } + + $('jg_voting').removeClass('jg_spinner'); + + // Show the voting result message + if($('jg_starrating_bar')) + { + new Element('div', {'id': 'jg_ajaxvoting_message', 'style': 'text-align: center;'}).inject($('jg_starrating_bar'), 'before'); + } + else + { + new Element('div', {'id': 'jg_ajaxvoting_message'}).inject($('ratingform'), 'before'); + } + $('jg_ajaxvoting_message').set('html', response.message); +} \ No newline at end of file diff --git a/deployed/joomgallery/media/joomgallery/js/dhtml.js b/deployed/joomgallery/media/joomgallery/js/dhtml.js new file mode 100644 index 00000000..8f91d91c --- /dev/null +++ b/deployed/joomgallery/media/joomgallery/js/dhtml.js @@ -0,0 +1,138 @@ +// $HeadURL: https://joomgallery.org/svn/joomgallery/JG-3/JG/trunk/media/joomgallery/js/dhtml.js $ +// $Id: dhtml.js 4078 2013-02-12 10:56:43Z erftralle $ +/****************************************************************************************\ +** JoomGallery 3 ** +** By: JoomGallery::ProjectTeam ** +** Copyright (C) 2008 - 2013 JoomGallery::ProjectTeam ** +** Based on: JoomGallery 1.0.0 by JoomGallery::ProjectTeam ** +** Released under GNU GPL Public License ** +** License: http://www.gnu.org/copyleft/gpl.html or have a look ** +** at administrator/components/com_joomgallery/LICENSE.TXT ** +\****************************************************************************************/ + +// This Script was written by Benjamin Meier, b2m@gmx.de +// modified by JoomGallery team +// The DHTML-function for creating a overlaying div-layer uses parts of the Dynamic Image Mambot, written by Manuel Hirsch +// and Lightbox => core code quirksmode.org +function joom_opendhtml(imgsource, imgtitle, imgtext, imgwidth, imgheight, baseURL) +{ + imgwidth = parseInt(imgwidth); + imgheight = parseInt(imgheight); + + var windowWidth, windowHeight; + if(self.innerHeight) + { + // all except Explorer + windowWidth = self.innerWidth; + windowHeight = self.innerHeight; + } + else if(document.documentElement && document.documentElement.clientHeight) + { + // Explorer 6 Strict Mode + windowWidth = document.documentElement.clientWidth; + windowHeight = document.documentElement.clientHeight; + } + else if(document.body) + { + // other Explorers + windowWidth = document.body.clientWidth; + windowHeight = document.body.clientHeight; + } + + var yScroll, xScroll; + + if(self.pageYOffset) + { + yScroll = self.pageYOffset; + xScroll = self.pageXOffset; + } + else if(document.documentElement && document.documentElement.scrollTop) + { + // Explorer 6 Strict + yScroll = document.documentElement.scrollTop; + xScroll = document.documentElement.scrollLeft; + } + else if(document.body) + { + // all other Explorers + yScroll = document.body.scrollTop; + xScroll = document.body.scrollLeft; + } + + if(resizeJsImage == 1) + { + if((imgwidth + 3 * jg_padding) > windowWidth) + { + imgheight = (imgheight * (windowWidth - 2 * jg_padding)) / imgwidth; + imgwidth = windowWidth-2*jg_padding; + } + if((imgheight + 2 * jg_padding + 80) > windowHeight) + { + imgwidth = (imgwidth * (windowHeight - 2 * jg_padding - 80)) / imgheight; + imgheight = windowHeight - 2 * jg_padding - 80; + } + } + var postop = (windowHeight / 2) - (imgheight / 2) + yScroll + document.body.style.padding - 10; + var posleft = (windowWidth / 2) - (imgwidth/ 2 ) + xScroll + document.body.style.padding; + if(postop >= 30) + { + postop = postop - 30; + } + var bodyObj = document.getElementsByTagName('BODY')[0]; + if(!document.getElementById("jg_photocontainer")) + { + divObjContainer = document.createElement("div"); + divObjContainer.setAttribute("id", "jg_photocontainer"); + bodyObj.appendChild(divObjContainer); + } + else + { + divObjContainer = document.getElementById("jg_photocontainer"); + } + + var closeimg = new Image(); + closeimg.src = baseURL + "media/joomgallery/images/close.png"; + var closeimgw = ""; + var closeimgh = ""; + if(closeimg.complete == true) + { + closeimgw = "width:" + closeimg.width + "px;"; + closeimgh = "height:" + closeimg.height + "px;"; + } + + var dhtmltext, dhtmltext2 = ""; + + divObjContainer.style.display = "block"; + dhtmltext = "
    "; + dhtmltext += "
    "; + dhtmltext += " \""+imgtitle+"\""; + dhtmltext += " \"close\""; + dhtmltext += "
    "; + dhtmltext += "
    "; + dhtmltext += "
    "; + divObjContainer.innerHTML = dhtmltext; + document.getElementById("joom_dhtml_imgtext").style.width2 = document.getElementById("joom_dhtml_imgtext").style.width-document.getElementById("dhtml_close").style.width; + if(imgtitle.length != 0) + { + dhtmltext2 = ""+imgtitle+""; + } + if(imgtext.length != 0) + { + dhtmltext2 = dhtmltext2 + ' ' + imgtext; + } + + if(dhtmltext2.length != 0) + { + document.getElementById("joom_dhtml_imgtext").innerHTML = dhtmltext2; + } + + if(jg_disableclick == 1) + { + divObjContainer.oncontextmenu = function(){return false;}; + } +} + +function joom_photocontainershut() +{ + document.getElementById("jg_photocontainer").style.display = "none"; +} diff --git a/deployed/joomgallery/media/joomgallery/js/fineuploader/edit.gif b/deployed/joomgallery/media/joomgallery/js/fineuploader/edit.gif new file mode 100644 index 00000000..13aa89a3 Binary files /dev/null and b/deployed/joomgallery/media/joomgallery/js/fineuploader/edit.gif differ diff --git a/deployed/joomgallery/media/joomgallery/js/fineuploader/fineuploader.css b/deployed/joomgallery/media/joomgallery/js/fineuploader/fineuploader.css new file mode 100644 index 00000000..795d328b --- /dev/null +++ b/deployed/joomgallery/media/joomgallery/js/fineuploader/fineuploader.css @@ -0,0 +1,245 @@ +/*! +* Fine Uploader +* +* Copyright 2013, Widen Enterprises, Inc. info@fineuploader.com +* +* Version: 4.4.0 +* +* Homepage: http://fineuploader.com +* +* Repository: git://github.com/Widen/fine-uploader.git +* +* Licensed under GNU GPL v3, see LICENSE +*/ + + +.qq-uploader { + position: relative; + width: 100%; +} +.qq-upload-button { + /* display: block; JG */ + width: auto; /* JG 105px; */ + padding: 7px 0; + text-align: center; + background: #880000; + border-bottom: 1px solid #DDD; + color: #FFF; +} +.qq-upload-button-hover { + background: #CC0000; +} +.qq-upload-button-focus { + outline: 1px dotted #000000; +} +.qq-upload-drop-area, .qq-upload-extra-drop-area { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + min-height: 30px; + z-index: 2; + background: #DFF0D8 /* JG #FF9797 */; + text-align: center; +} +.qq-upload-drop-area span { + display: block; + position: absolute; + top: 50%; + width: 100%; + margin-top: -8px; + font-size: 16px; +} +.qq-upload-extra-drop-area { + position: relative; + margin-top: 50px; + font-size: 16px; + padding-top: 30px; + height: 20px; + min-height: 40px; +} +.qq-upload-drop-area-active { + background: #5BB75B /* JG #FF7171 */; +} +.qq-upload-list { + margin: 10px 0 0 0; /* JG 0 */ + padding: 0; + list-style: none; +} +.qq-upload-list li { + margin: 4px 0 0 0; /* JG 0 */ + /* JG + padding: 9px; + line-height: 15px; + font-size: 16px; + background-color: #FFF0BD; + */ + padding: 8px 35px 8px 14px; /* JG */ +} +.qq-upload-file, .qq-upload-spinner, .qq-upload-size, +.qq-upload-cancel, .qq-upload-retry, .qq-upload-failed-text, +.qq-upload-delete, .qq-upload-pause, .qq-upload-continue { + margin-right: 12px; + display: inline; +} +.qq-upload-file { +} +.qq-upload-spinner { + display: inline-block; + background: url("loading.gif"); + width: 15px; + height: 15px; + vertical-align: text-bottom; +} +.qq-drop-processing { + display: block; +} +.qq-drop-processing-spinner { + display: inline-block; + background: url("processing.gif"); + width: 24px; + height: 24px; + vertical-align: text-bottom; +} + +.qq-upload-delete, .qq-upload-pause, .qq-upload-continue { + display: inline; +} + +.qq-upload-retry, .qq-upload-delete, .qq-upload-cancel, +.qq-upload-pause, .qq-upload-continue { + /* color: #000000; JG */ +} + +.qq-upload-retryable .qq-upload-retry { + display: inline; +} +.qq-upload-size, .qq-upload-cancel, .qq-upload-retry, +.qq-upload-delete, .qq-upload-pause, .qq-upload-continue { + /* JG + font-size: 12px; + font-weight: normal; + */ +} +.qq-upload-failed-text { + display: none; + font-style: italic; + font-weight: bold; +} +.qq-upload-failed-icon { + display:none; + width:15px; + height:15px; + vertical-align:text-bottom; +} +.qq-upload-fail .qq-upload-failed-text { + display: inline; +} +.qq-upload-retrying .qq-upload-failed-text { + display: inline; + color: #D60000; +} +.qq-upload-list li.qq-upload-success { + background-color: #5DA30C; + color: #FFFFFF; +} +.qq-upload-list li.qq-upload-fail { + background-color: #D60000; + color: #FFFFFF; +} +.qq-progress-bar { + display: block; + background: -moz-linear-gradient(top, rgba(30,87,153,1) 0%, rgba(41,137,216,1) 50%, rgba(32,124,202,1) 51%, rgba(125,185,232,1) 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(30,87,153,1)), color-stop(50%,rgba(41,137,216,1)), color-stop(51%,rgba(32,124,202,1)), color-stop(100%,rgba(125,185,232,1))); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, rgba(30,87,153,1) 0%,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(top, rgba(30,87,153,1) 0%,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%); /* Opera 11.10+ */ + background: -ms-linear-gradient(top, rgba(30,87,153,1) 0%,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%); /* IE10+ */ + background: linear-gradient(to bottom, rgba(30,87,153,1) 0%,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%); /* W3C */ + width: 0%; + height: 15px; + border-radius: 6px; + margin-bottom: 3px; +} + +.qq-total-progress-bar { + height: 25px; + border-radius: 9px; +} + +.qq-total-progress-bar-container { + margin: 9px; +} +/* JG START */ +.qq-upload-debug-text { + display: block; +} + +div#triggerClearUploadList { + margin-bottom: 5px; +} + +.qq-upload-button input[type="file"] { + height: 100%; +} +/* JG END */ + +INPUT.qq-edit-filename { + position: absolute; + opacity: 0; + filter: alpha(opacity=0); + z-index: -1; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; +} + +.qq-upload-file.qq-editable { + cursor: pointer; +} + +.qq-edit-filename-icon.qq-editable { + display: inline-block; + cursor: pointer; +} + +INPUT.qq-edit-filename.qq-editing { + position: static; + margin-top: -5px; + margin-right: 10px; + margin-bottom: -5px; + + opacity: 1; + filter: alpha(opacity=100); + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +} + +.qq-edit-filename-icon { + display: none; + background: url("edit.gif"); + width: 15px; + height: 15px; + vertical-align: text-bottom; + margin-right: 5px; +} + +INPUT.qq-edit-filename.qq-editing ~ .qq-upload-cancel { + display: none; +} + +.qq-hide { + display: none !important; /* JG display: none; */ +} + +/* JG START */ +INPUT.qq-edit-imgtitle.qq-editing { + display: block; + position: static; + margin-top: 5px; + margin-right: 10px; + margin-bottom: -5px; + opacity: 1; + filter: alpha(opacity=100); + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +} +/* JG END */ + +/*! 2014-04-27 */ diff --git a/deployed/joomgallery/media/joomgallery/js/fineuploader/js/fineuploader.js b/deployed/joomgallery/media/joomgallery/js/fineuploader/js/fineuploader.js new file mode 100644 index 00000000..db64aa00 --- /dev/null +++ b/deployed/joomgallery/media/joomgallery/js/fineuploader/js/fineuploader.js @@ -0,0 +1,10212 @@ +/*! +* Fine Uploader +* +* Copyright 2013, Widen Enterprises, Inc. info@fineuploader.com +* +* Version: 4.4.0 +* +* Homepage: http://fineuploader.com +* +* Repository: git://github.com/Widen/fine-uploader.git +* +* Licensed under GNU GPL v3, see LICENSE +*/ + + +/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */ +/* jshint -W079 */ +var qq = function(element) { + "use strict"; + + return { + hide: function() { + element.style.display = "none"; + return this; + }, + + /** Returns the function which detaches attached event */ + attach: function(type, fn) { + if (element.addEventListener){ + element.addEventListener(type, fn, false); + } else if (element.attachEvent){ + element.attachEvent("on" + type, fn); + } + return function() { + qq(element).detach(type, fn); + }; + }, + + detach: function(type, fn) { + if (element.removeEventListener){ + element.removeEventListener(type, fn, false); + } else if (element.attachEvent){ + element.detachEvent("on" + type, fn); + } + return this; + }, + + contains: function(descendant) { + // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains) + // says a `null` (or ostensibly `undefined`) parameter + // passed into `Node.contains` should result in a false return value. + // IE7 throws an exception if the parameter is `undefined` though. + if (!descendant) { + return false; + } + + // compareposition returns false in this case + if (element === descendant) { + return true; + } + + if (element.contains){ + return element.contains(descendant); + } else { + /*jslint bitwise: true*/ + return !!(descendant.compareDocumentPosition(element) & 8); + } + }, + + /** + * Insert this element before elementB. + */ + insertBefore: function(elementB) { + elementB.parentNode.insertBefore(element, elementB); + return this; + }, + + remove: function() { + element.parentNode.removeChild(element); + return this; + }, + + /** + * Sets styles for an element. + * Fixes opacity in IE6-8. + */ + css: function(styles) { + /*jshint eqnull: true*/ + if (element.style == null) { + throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!"); + } + + /*jshint -W116*/ + if (styles.opacity != null){ + if (typeof element.style.opacity !== "string" && typeof(element.filters) !== "undefined"){ + styles.filter = "alpha(opacity=" + Math.round(100 * styles.opacity) + ")"; + } + } + qq.extend(element.style, styles); + + return this; + }, + + hasClass: function(name) { + var re = new RegExp("(^| )" + name + "( |$)"); + return re.test(element.className); + }, + + addClass: function(name) { + if (!qq(element).hasClass(name)){ + element.className += " " + name; + } + return this; + }, + + removeClass: function(name) { + var re = new RegExp("(^| )" + name + "( |$)"); + element.className = element.className.replace(re, " ").replace(/^\s+|\s+$/g, ""); + return this; + }, + + getByClass: function(className) { + var candidates, + result = []; + + if (element.querySelectorAll){ + return element.querySelectorAll("." + className); + } + + candidates = element.getElementsByTagName("*"); + + qq.each(candidates, function(idx, val) { + if (qq(val).hasClass(className)){ + result.push(val); + } + }); + return result; + }, + + children: function() { + var children = [], + child = element.firstChild; + + while (child){ + if (child.nodeType === 1){ + children.push(child); + } + child = child.nextSibling; + } + + return children; + }, + + setText: function(text) { + element.innerText = text; + element.textContent = text; + return this; + }, + + clearText: function() { + return qq(element).setText(""); + }, + + // Returns true if the attribute exists on the element + // AND the value of the attribute is NOT "false" (case-insensitive) + hasAttribute: function(attrName) { + var attrVal; + + if (element.hasAttribute) { + + if (!element.hasAttribute(attrName)) { + return false; + } + + /*jshint -W116*/ + return (/^false$/i).exec(element.getAttribute(attrName)) == null; + } + else { + attrVal = element[attrName]; + + if (attrVal === undefined) { + return false; + } + + /*jshint -W116*/ + return (/^false$/i).exec(attrVal) == null; + } + } + }; +}; + +(function(){ + "use strict"; + + qq.log = function(message, level) { + if (window.console) { + if (!level || level === "info") { + window.console.log(message); + } + else + { + if (window.console[level]) { + window.console[level](message); + } + else { + window.console.log("<" + level + "> " + message); + } + } + } + }; + + qq.isObject = function(variable) { + return variable && !variable.nodeType && Object.prototype.toString.call(variable) === "[object Object]"; + }; + + qq.isFunction = function(variable) { + return typeof(variable) === "function"; + }; + + /** + * Check the type of a value. Is it an "array"? + * + * @param value value to test. + * @returns true if the value is an array or associated with an `ArrayBuffer` + */ + qq.isArray = function(value) { + return Object.prototype.toString.call(value) === "[object Array]" || + (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer); + }; + + // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API. + qq.isItemList = function(maybeItemList) { + return Object.prototype.toString.call(maybeItemList) === "[object DataTransferItemList]"; + }; + + // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement` + // object that is associated with collections of Nodes. + qq.isNodeList = function(maybeNodeList) { + return Object.prototype.toString.call(maybeNodeList) === "[object NodeList]" || + // If `HTMLCollection` is the actual type of the object, we must determine this + // by checking for expected properties/methods on the object + (maybeNodeList.item && maybeNodeList.namedItem); + }; + + qq.isString = function(maybeString) { + return Object.prototype.toString.call(maybeString) === "[object String]"; + }; + + qq.trimStr = function(string) { + if (String.prototype.trim) { + return string.trim(); + } + + return string.replace(/^\s+|\s+$/g,""); + }; + + + /** + * @param str String to format. + * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string. + */ + qq.format = function(str) { + + var args = Array.prototype.slice.call(arguments, 1), + newStr = str, + nextIdxToReplace = newStr.indexOf("{}"); + + qq.each(args, function(idx, val) { + var strBefore = newStr.substring(0, nextIdxToReplace), + strAfter = newStr.substring(nextIdxToReplace+2); + + newStr = strBefore + val + strAfter; + nextIdxToReplace = newStr.indexOf("{}", nextIdxToReplace + val.length); + + // End the loop if we have run out of tokens (when the arguments exceed the # of tokens) + if (nextIdxToReplace < 0) { + return false; + } + }); + + return newStr; + }; + + qq.isFile = function(maybeFile) { + return window.File && Object.prototype.toString.call(maybeFile) === "[object File]"; + }; + + qq.isFileList = function(maybeFileList) { + return window.FileList && Object.prototype.toString.call(maybeFileList) === "[object FileList]"; + }; + + qq.isFileOrInput = function(maybeFileOrInput) { + return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput); + }; + + qq.isInput = function(maybeInput, notFile) { + var evaluateType = function(type) { + var normalizedType = type.toLowerCase(); + + if (notFile) { + return normalizedType !== "file"; + } + + return normalizedType === "file"; + }; + + if (window.HTMLInputElement) { + if (Object.prototype.toString.call(maybeInput) === "[object HTMLInputElement]") { + if (maybeInput.type && evaluateType(maybeInput.type)) { + return true; + } + } + } + if (maybeInput.tagName) { + if (maybeInput.tagName.toLowerCase() === "input") { + if (maybeInput.type && evaluateType(maybeInput.type)) { + return true; + } + } + } + + return false; + }; + + qq.isBlob = function(maybeBlob) { + if (window.Blob && Object.prototype.toString.call(maybeBlob) === "[object Blob]") { + return true; + } + }; + + qq.isXhrUploadSupported = function() { + var input = document.createElement("input"); + input.type = "file"; + + return ( + input.multiple !== undefined && + typeof File !== "undefined" && + typeof FormData !== "undefined" && + typeof (qq.createXhrInstance()).upload !== "undefined" ); + }; + + // Fall back to ActiveX is native XHR is disabled (possible in any version of IE). + qq.createXhrInstance = function() { + if (window.XMLHttpRequest) { + return new XMLHttpRequest(); + } + + try { + return new ActiveXObject("MSXML2.XMLHTTP.3.0"); + } + catch(error) { + qq.log("Neither XHR or ActiveX are supported!", "error"); + return null; + } + }; + + qq.isFolderDropSupported = function(dataTransfer) { + return (dataTransfer.items && dataTransfer.items[0].webkitGetAsEntry); + }; + + qq.isFileChunkingSupported = function() { + return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly + qq.isXhrUploadSupported() && + (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined); + }; + + qq.sliceBlob = function(fileOrBlob, start, end) { + var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice; + + return slicer.call(fileOrBlob, start, end); + }; + + qq.arrayBufferToHex = function(buffer) { + var bytesAsHex = "", + bytes = new Uint8Array(buffer); + + + qq.each(bytes, function(idx, byte) { + var byteAsHexStr = byte.toString(16); + + if (byteAsHexStr.length < 2) { + byteAsHexStr = "0" + byteAsHexStr; + } + + bytesAsHex += byteAsHexStr; + }); + + return bytesAsHex; + }; + + qq.readBlobToHex = function(blob, startOffset, length) { + var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length), + fileReader = new FileReader(), + promise = new qq.Promise(); + + fileReader.onload = function() { + promise.success(qq.arrayBufferToHex(fileReader.result)); + }; + + fileReader.onerror = promise.failure; + + fileReader.readAsArrayBuffer(initialBlob); + + return promise; + }; + + qq.extend = function(first, second, extendNested) { + qq.each(second, function(prop, val) { + if (extendNested && qq.isObject(val)) { + if (first[prop] === undefined) { + first[prop] = {}; + } + qq.extend(first[prop], val, true); + } + else { + first[prop] = val; + } + }); + + return first; + }; + + /** + * Allow properties in one object to override properties in another, + * keeping track of the original values from the target object. + * + * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked. + * + * @param target Update properties in this object from some source + * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target. + * @returns {object} The target object + */ + qq.override = function(target, sourceFn) { + var super_ = {}, + source = sourceFn(super_); + + qq.each(source, function(srcPropName, srcPropVal) { + if (target[srcPropName] !== undefined) { + super_[srcPropName] = target[srcPropName]; + } + + target[srcPropName] = srcPropVal; + }); + + return target; + }; + + /** + * Searches for a given element in the array, returns -1 if it is not present. + * @param {Number} [from] The index at which to begin the search + */ + qq.indexOf = function(arr, elt, from){ + if (arr.indexOf) { + return arr.indexOf(elt, from); + } + + from = from || 0; + var len = arr.length; + + if (from < 0) { + from += len; + } + + for (; from < len; from+=1){ + if (arr.hasOwnProperty(from) && arr[from] === elt){ + return from; + } + } + return -1; + }; + + //this is a version 4 UUID + qq.getUniqueId = function(){ + return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) { + /*jslint eqeq: true, bitwise: true*/ + var r = Math.random()*16|0, v = c == "x" ? r : (r&0x3|0x8); + return v.toString(16); + }); + }; + + // + // Browsers and platforms detection + qq.ie = function() { + return navigator.userAgent.indexOf("MSIE") !== -1; + }; + + qq.ie7 = function() { + return navigator.userAgent.indexOf("MSIE 7") !== -1; + }; + + qq.ie10 = function() { + return navigator.userAgent.indexOf("MSIE 10") !== -1; + }; + + qq.ie11 = function() { + return (navigator.userAgent.indexOf("Trident") !== -1 && + navigator.userAgent.indexOf("rv:11") !== -1); + }; + + qq.safari = function() { + return navigator.vendor !== undefined && navigator.vendor.indexOf("Apple") !== -1; + }; + + qq.chrome = function() { + return navigator.vendor !== undefined && navigator.vendor.indexOf("Google") !== -1; + }; + + qq.opera = function() { + return navigator.vendor !== undefined && navigator.vendor.indexOf("Opera") !== -1; + }; + + qq.firefox = function() { + return (!qq.ie11() && navigator.userAgent.indexOf("Mozilla") !== -1 && navigator.vendor !== undefined && navigator.vendor === ""); + }; + + qq.windows = function() { + return navigator.platform === "Win32"; + }; + + qq.android = function() { + return navigator.userAgent.toLowerCase().indexOf("android") !== -1; + }; + + // We need to identify the Android stock browser via the UA string to work around various bugs in this browser, + // such as the one that prevents a `Blob` from being uploaded. + qq.androidStock = function() { + return qq.android() && navigator.userAgent.toLowerCase().indexOf("chrome") < 0; + }; + + qq.ios7 = function() { + return qq.ios() && navigator.userAgent.indexOf(" OS 7_") !== -1; + }; + + qq.ios = function() { + /*jshint -W014 */ + return navigator.userAgent.indexOf("iPad") !== -1 + || navigator.userAgent.indexOf("iPod") !== -1 + || navigator.userAgent.indexOf("iPhone") !== -1; + }; + + // + // Events + + qq.preventDefault = function(e){ + if (e.preventDefault){ + e.preventDefault(); + } else{ + e.returnValue = false; + } + }; + + /** + * Creates and returns element from html string + * Uses innerHTML to create an element + */ + qq.toElement = (function(){ + var div = document.createElement("div"); + return function(html){ + div.innerHTML = html; + var element = div.firstChild; + div.removeChild(element); + return element; + }; + }()); + + //key and value are passed to callback for each entry in the iterable item + qq.each = function(iterableItem, callback) { + var keyOrIndex, retVal; + + if (iterableItem) { + // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items + if (window.Storage && iterableItem.constructor === window.Storage) { + for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) { + retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex))); + if (retVal === false) { + break; + } + } + } + // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays + // when iterating over items inside the object. + else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) { + for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) { + retVal = callback(keyOrIndex, iterableItem[keyOrIndex]); + if (retVal === false) { + break; + } + } + } + else if (qq.isString(iterableItem)) { + for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) { + retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex)); + if (retVal === false) { + break; + } + } + } + else { + for (keyOrIndex in iterableItem) { + if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) { + retVal = callback(keyOrIndex, iterableItem[keyOrIndex]); + if (retVal === false) { + break; + } + } + } + } + } + }; + + //include any args that should be passed to the new function after the context arg + qq.bind = function(oldFunc, context) { + if (qq.isFunction(oldFunc)) { + var args = Array.prototype.slice.call(arguments, 2); + + return function() { + var newArgs = qq.extend([], args); + if (arguments.length) { + newArgs = newArgs.concat(Array.prototype.slice.call(arguments)); + } + return oldFunc.apply(context, newArgs); + }; + } + + throw new Error("first parameter must be a function!"); + }; + + /** + * obj2url() takes a json-object as argument and generates + * a querystring. pretty much like jQuery.param() + * + * how to use: + * + * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');` + * + * will result in: + * + * `http://any.url/upload?otherParam=value&a=b&c=d` + * + * @param Object JSON-Object + * @param String current querystring-part + * @return String encoded querystring + */ + qq.obj2url = function(obj, temp, prefixDone){ + /*jshint laxbreak: true*/ + var uristrings = [], + prefix = "&", + add = function(nextObj, i){ + var nextTemp = temp + ? (/\[\]$/.test(temp)) // prevent double-encoding + ? temp + : temp+"["+i+"]" + : i; + if ((nextTemp !== "undefined") && (i !== "undefined")) { + uristrings.push( + (typeof nextObj === "object") + ? qq.obj2url(nextObj, nextTemp, true) + : (Object.prototype.toString.call(nextObj) === "[object Function]") + ? encodeURIComponent(nextTemp) + "=" + encodeURIComponent(nextObj()) + : encodeURIComponent(nextTemp) + "=" + encodeURIComponent(nextObj) + ); + } + }; + + if (!prefixDone && temp) { + prefix = (/\?/.test(temp)) ? (/\?$/.test(temp)) ? "" : "&" : "?"; + uristrings.push(temp); + uristrings.push(qq.obj2url(obj)); + } else if ((Object.prototype.toString.call(obj) === "[object Array]") && (typeof obj !== "undefined") ) { + qq.each(obj, function(idx, val) { + add(val, idx); + }); + } else if ((typeof obj !== "undefined") && (obj !== null) && (typeof obj === "object")){ + qq.each(obj, function(prop, val) { + add(val, prop); + }); + } else { + uristrings.push(encodeURIComponent(temp) + "=" + encodeURIComponent(obj)); + } + + if (temp) { + return uristrings.join(prefix); + } else { + return uristrings.join(prefix) + .replace(/^&/, "") + .replace(/%20/g, "+"); + } + }; + + qq.obj2FormData = function(obj, formData, arrayKeyName) { + if (!formData) { + formData = new FormData(); + } + + qq.each(obj, function(key, val) { + key = arrayKeyName ? arrayKeyName + "[" + key + "]" : key; + + if (qq.isObject(val)) { + qq.obj2FormData(val, formData, key); + } + else if (qq.isFunction(val)) { + formData.append(key, val()); + } + else { + formData.append(key, val); + } + }); + + return formData; + }; + + qq.obj2Inputs = function(obj, form) { + var input; + + if (!form) { + form = document.createElement("form"); + } + + qq.obj2FormData(obj, { + append: function(key, val) { + input = document.createElement("input"); + input.setAttribute("name", key); + input.setAttribute("value", val); + form.appendChild(input); + } + }); + + return form; + }; + + qq.setCookie = function(name, value, days) { + var date = new Date(), + expires = ""; + + if (days) { + date.setTime(date.getTime()+(days*24*60*60*1000)); + expires = "; expires="+date.toGMTString(); + } + + document.cookie = name+"="+value+expires+"; path=/"; + }; + + qq.getCookie = function(name) { + var nameEQ = name + "=", + ca = document.cookie.split(";"), + cookie; + + qq.each(ca, function(idx, part) { + /*jshint -W116 */ + var cookiePart = part; + while (cookiePart.charAt(0) == " ") { + cookiePart = cookiePart.substring(1, cookiePart.length); + } + + if (cookiePart.indexOf(nameEQ) === 0) { + cookie = cookiePart.substring(nameEQ.length, cookiePart.length); + return false; + } + }); + + return cookie; + }; + + qq.getCookieNames = function(regexp) { + var cookies = document.cookie.split(";"), + cookieNames = []; + + qq.each(cookies, function(idx, cookie) { + cookie = qq.trimStr(cookie); + + var equalsIdx = cookie.indexOf("="); + + if (cookie.match(regexp)) { + cookieNames.push(cookie.substr(0, equalsIdx)); + } + }); + + return cookieNames; + }; + + qq.deleteCookie = function(name) { + qq.setCookie(name, "", -1); + }; + + qq.areCookiesEnabled = function() { + var randNum = Math.random() * 100000, + name = "qqCookieTest:" + randNum; + qq.setCookie(name, 1); + + if (qq.getCookie(name)) { + qq.deleteCookie(name); + return true; + } + return false; + }; + + /** + * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not + * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js. + */ + qq.parseJson = function(json) { + /*jshint evil: true*/ + if (window.JSON && qq.isFunction(JSON.parse)) { + return JSON.parse(json); + } else { + return eval("(" + json + ")"); + } + }; + + /** + * Retrieve the extension of a file, if it exists. + * + * @param filename + * @returns {string || undefined} + */ + qq.getExtension = function(filename) { + var extIdx = filename.lastIndexOf(".") + 1; + + if (extIdx > 0) { + return filename.substr(extIdx, filename.length - extIdx); + } + }; + + qq.getFilename = function(blobOrFileInput) { + /*jslint regexp: true*/ + + if (qq.isInput(blobOrFileInput)) { + // get input value and remove path to normalize + return blobOrFileInput.value.replace(/.*(\/|\\)/, ""); + } + else if (qq.isFile(blobOrFileInput)) { + if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) { + return blobOrFileInput.fileName; + } + } + + return blobOrFileInput.name; + }; + + /** + * A generic module which supports object disposing in dispose() method. + * */ + qq.DisposeSupport = function() { + var disposers = []; + + return { + /** Run all registered disposers */ + dispose: function() { + var disposer; + do { + disposer = disposers.shift(); + if (disposer) { + disposer(); + } + } + while (disposer); + }, + + /** Attach event handler and register de-attacher as a disposer */ + attach: function() { + var args = arguments; + /*jslint undef:true*/ + this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1))); + }, + + /** Add disposer to the collection */ + addDisposer: function(disposeFunction) { + disposers.push(disposeFunction); + } + }; + }; +}()); + +/* globals qq */ +/** + * Fine Uploader top-level Error container. Inherits from `Error`. + */ +(function() { + "use strict"; + + qq.Error = function(message) { + this.message = "[Fine Uploader " + qq.version + "] " + message; + }; + + qq.Error.prototype = new Error(); +}()); + +/*global qq */ +qq.version="4.4.0"; + +/* globals qq */ +qq.supportedFeatures = (function () { + "use strict"; + + var supportsUploading, + supportsUploadingBlobs, + supportsAjaxFileUploading, + supportsFolderDrop, + supportsChunking, + supportsResume, + supportsUploadViaPaste, + supportsUploadCors, + supportsDeleteFileXdr, + supportsDeleteFileCorsXhr, + supportsDeleteFileCors, + supportsFolderSelection, + supportsImagePreviews, + supportsUploadProgress; + + + function testSupportsFileInputElement() { + var supported = true, + tempInput; + + try { + tempInput = document.createElement("input"); + tempInput.type = "file"; + qq(tempInput).hide(); + + if (tempInput.disabled) { + supported = false; + } + } + catch (ex) { + supported = false; + } + + return supported; + } + + //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface + function isChrome21OrHigher() { + return (qq.chrome() || qq.opera()) && + navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/) !== undefined; + } + + //only way to test for complete Clipboard API support at this time + function isChrome14OrHigher() { + return (qq.chrome() || qq.opera()) && + navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/) !== undefined; + } + + //Ensure we can send cross-origin `XMLHttpRequest`s + function isCrossOriginXhrSupported() { + if (window.XMLHttpRequest) { + var xhr = qq.createXhrInstance(); + + //Commonly accepted test for XHR CORS support. + return xhr.withCredentials !== undefined; + } + + return false; + } + + //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8 + function isXdrSupported() { + return window.XDomainRequest !== undefined; + } + + // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s, + // or if `XDomainRequest` is an available alternative. + function isCrossOriginAjaxSupported() { + if (isCrossOriginXhrSupported()) { + return true; + } + + return isXdrSupported(); + } + + function isFolderSelectionSupported() { + // We know that folder selection is only supported in Chrome via this proprietary attribute for now + return document.createElement("input").webkitdirectory !== undefined; + } + + + supportsUploading = testSupportsFileInputElement(); + + supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported(); + + supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock(); + + supportsFolderDrop = supportsAjaxFileUploading && isChrome21OrHigher(); + + supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported(); + + supportsResume = supportsAjaxFileUploading && supportsChunking && qq.areCookiesEnabled(); + + supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher(); + + supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading); + + supportsDeleteFileCorsXhr = isCrossOriginXhrSupported(); + + supportsDeleteFileXdr = isXdrSupported(); + + supportsDeleteFileCors = isCrossOriginAjaxSupported(); + + supportsFolderSelection = isFolderSelectionSupported(); + + supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined; + + supportsUploadProgress = (function() { + if (supportsAjaxFileUploading) { + return !qq.androidStock() && + !(qq.ios() && navigator.userAgent.indexOf("CriOS") >= 0); + } + return false; + }()); + + + return { + ajaxUploading: supportsAjaxFileUploading, + blobUploading: supportsUploadingBlobs, + canDetermineSize: supportsAjaxFileUploading, + chunking: supportsChunking, + deleteFileCors: supportsDeleteFileCors, + deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported + deleteFileCorsXhr: supportsDeleteFileCorsXhr, + fileDrop: supportsAjaxFileUploading, //NOTE: will also return true for touch-only devices. It's not currently possible to accurately test for touch-only devices + folderDrop: supportsFolderDrop, + folderSelection: supportsFolderSelection, + imagePreviews: supportsImagePreviews, + imageValidation: supportsImagePreviews, + itemSizeValidation: supportsAjaxFileUploading, + pause: supportsChunking, + progressBar: supportsUploadProgress, + resume: supportsResume, + scaling: supportsImagePreviews && supportsUploadingBlobs, + tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now) + uploading: supportsUploading, + uploadCors: supportsUploadCors, + uploadCustomHeaders: supportsAjaxFileUploading, + uploadNonMultipart: supportsAjaxFileUploading, + uploadViaPaste: supportsUploadViaPaste + }; + +}()); + +/*globals qq*/ +qq.Promise = function() { + "use strict"; + + var successArgs, failureArgs, + successCallbacks = [], + failureCallbacks = [], + doneCallbacks = [], + state = 0; + + qq.extend(this, { + then: function(onSuccess, onFailure) { + if (state === 0) { + if (onSuccess) { + successCallbacks.push(onSuccess); + } + if (onFailure) { + failureCallbacks.push(onFailure); + } + } + else if (state === -1) { + onFailure && onFailure.apply(null, failureArgs); + } + else if (onSuccess) { + onSuccess.apply(null,successArgs); + } + + return this; + }, + + done: function(callback) { + if (state === 0) { + doneCallbacks.push(callback); + } + else { + callback.apply(null, failureArgs === undefined ? successArgs : failureArgs); + } + + return this; + }, + + success: function() { + state = 1; + successArgs = arguments; + + if (successCallbacks.length) { + qq.each(successCallbacks, function(idx, callback) { + callback.apply(null, successArgs); + }); + } + + if(doneCallbacks.length) { + qq.each(doneCallbacks, function(idx, callback) { + callback.apply(null, successArgs); + }); + } + + return this; + }, + + failure: function() { + state = -1; + failureArgs = arguments; + + if (failureCallbacks.length) { + qq.each(failureCallbacks, function(idx, callback) { + callback.apply(null, failureArgs); + }); + } + + if(doneCallbacks.length) { + qq.each(doneCallbacks, function(idx, callback) { + callback.apply(null, failureArgs); + }); + } + + return this; + } + }); +}; + +/* globals qq */ +/** + * Placeholder for a Blob that will be generated on-demand. + * + * @param referenceBlob Parent of the generated blob + * @param onCreate Function to invoke when the blob must be created. Must be promissory. + * @constructor + */ +qq.BlobProxy = function(referenceBlob, onCreate) { + "use strict"; + + qq.extend(this, { + referenceBlob: referenceBlob, + + create: function() { + return onCreate(referenceBlob); + } + }); +}; + +/*globals qq*/ + +/** + * This module represents an upload or "Select File(s)" button. It's job is to embed an opaque `` + * element as a child of a provided "container" element. This "container" element (`options.element`) is used to provide + * a custom style for the `` element. The ability to change the style of the container element is also + * provided here by adding CSS classes to the container on hover/focus. + * + * TODO Eliminate the mouseover and mouseout event handlers since the :hover CSS pseudo-class should now be + * available on all supported browsers. + * + * @param o Options to override the default values + */ +qq.UploadButton = function(o) { + "use strict"; + + + var disposeSupport = new qq.DisposeSupport(), + + options = { + // "Container" element + element: null, + + // If true adds `multiple` attribute to `` + multiple: false, + + // Corresponds to the `accept` attribute on the associated `` + acceptFiles: null, + + // A true value allows folders to be selected, if supported by the UA + folders: false, + + // `name` attribute of `` + name: "qqfile", + + // Called when the browser invokes the onchange handler on the `` + onChange: function(input) {}, + + // **This option will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers + hoverClass: "qq-upload-button-hover", + + focusClass: "qq-upload-button-focus" + }, + input, buttonId; + + // Overrides any of the default option values with any option values passed in during construction. + qq.extend(options, o); + + buttonId = qq.getUniqueId(); + + // Embed an opaque `` element as a child of `options.element`. + function createInput() { + var input = document.createElement("input"); + + input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId); + + if (options.multiple) { + input.setAttribute("multiple", ""); + } + + if (options.folders && qq.supportedFeatures.folderSelection) { + // selecting directories is only possible in Chrome now, via a vendor-specific prefixed attribute + input.setAttribute("webkitdirectory", ""); + } + + if (options.acceptFiles) { + input.setAttribute("accept", options.acceptFiles); + } + + input.setAttribute("type", "file"); + input.setAttribute("name", options.name); + + qq(input).css({ + position: "absolute", + // in Opera only 'browse' button + // is clickable and it is located at + // the right side of the input + right: 0, + top: 0, + fontFamily: "Arial", + // 4 persons reported this, the max values that worked for them were 243, 236, 236, 118 + fontSize: "118px", + margin: 0, + padding: 0, + cursor: "pointer", + opacity: 0 + }); + + options.element.appendChild(input); + + disposeSupport.attach(input, "change", function(){ + options.onChange(input); + }); + + // **These event handlers will be removed** in the future as the :hover CSS pseudo-class is available on all supported browsers + disposeSupport.attach(input, "mouseover", function(){ + qq(options.element).addClass(options.hoverClass); + }); + disposeSupport.attach(input, "mouseout", function(){ + qq(options.element).removeClass(options.hoverClass); + }); + + disposeSupport.attach(input, "focus", function(){ + qq(options.element).addClass(options.focusClass); + }); + disposeSupport.attach(input, "blur", function(){ + qq(options.element).removeClass(options.focusClass); + }); + + // IE and Opera, unfortunately have 2 tab stops on file input + // which is unacceptable in our case, disable keyboard access + if (window.attachEvent) { + // it is IE or Opera + input.setAttribute("tabIndex", "-1"); + } + + return input; + } + + // Make button suitable container for input + qq(options.element).css({ + position: "relative", + overflow: "hidden", + // Make sure browse button is in the right side in Internet Explorer + direction: "ltr" + }); + + input = createInput(); + + + // Exposed API + qq.extend(this, { + getInput: function() { + return input; + }, + + getButtonId: function() { + return buttonId; + }, + + setMultiple: function(isMultiple) { + if (isMultiple !== options.multiple) { + if (isMultiple) { + input.setAttribute("multiple", ""); + } + else { + input.removeAttribute("multiple"); + } + } + }, + + setAcceptFiles: function(acceptFiles) { + if (acceptFiles !== options.acceptFiles) { + input.setAttribute("accept", acceptFiles); + } + }, + + reset: function(){ + if (input.parentNode){ + qq(input).remove(); + } + + qq(options.element).removeClass(options.focusClass); + input = createInput(); + } + }); +}; + +qq.UploadButton.BUTTON_ID_ATTR_NAME = "qq-button-id"; + +/*globals qq */ +qq.UploadData = function(uploaderProxy) { + "use strict"; + + var data = [], + byUuid = {}, + byStatus = {}; + + + function getDataByIds(idOrIds) { + if (qq.isArray(idOrIds)) { + var entries = []; + + qq.each(idOrIds, function(idx, id) { + entries.push(data[id]); + }); + + return entries; + } + + return data[idOrIds]; + } + + function getDataByUuids(uuids) { + if (qq.isArray(uuids)) { + var entries = []; + + qq.each(uuids, function(idx, uuid) { + entries.push(data[byUuid[uuid]]); + }); + + return entries; + } + + return data[byUuid[uuids]]; + } + + function getDataByStatus(status) { + var statusResults = [], + statuses = [].concat(status); + + qq.each(statuses, function(index, statusEnum) { + var statusResultIndexes = byStatus[statusEnum]; + + if (statusResultIndexes !== undefined) { + qq.each(statusResultIndexes, function(i, dataIndex) { + statusResults.push(data[dataIndex]); + }); + } + }); + + return statusResults; + } + + qq.extend(this, { + /** + * Adds a new file to the data cache for tracking purposes. + * + * @param uuid Initial UUID for this file. + * @param name Initial name of this file. + * @param size Size of this file, -1 if this cannot be determined + * @param status Initial `qq.status` for this file. If null/undefined, `qq.status.SUBMITTING`. + * @returns {number} Internal ID for this file. + */ + addFile: function(uuid, name, size, status) { + status = status || qq.status.SUBMITTING; + + var id = data.push({ + name: name, + originalName: name, + uuid: uuid, + size: size, + status: status + }) - 1; + + data[id].id = id; + byUuid[uuid] = id; + + if (byStatus[status] === undefined) { + byStatus[status] = []; + } + byStatus[status].push(id); + + uploaderProxy.onStatusChange(id, null, status); + + return id; + }, + + retrieve: function(optionalFilter) { + if (qq.isObject(optionalFilter) && data.length) { + if (optionalFilter.id !== undefined) { + return getDataByIds(optionalFilter.id); + } + + else if (optionalFilter.uuid !== undefined) { + return getDataByUuids(optionalFilter.uuid); + } + + else if (optionalFilter.status) { + return getDataByStatus(optionalFilter.status); + } + } + else { + return qq.extend([], data, true); + } + }, + + reset: function() { + data = []; + byUuid = {}; + byStatus = {}; + }, + + setStatus: function(id, newStatus) { + var oldStatus = data[id].status, + byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id); + + byStatus[oldStatus].splice(byStatusOldStatusIndex, 1); + + data[id].status = newStatus; + + if (byStatus[newStatus] === undefined) { + byStatus[newStatus] = []; + } + byStatus[newStatus].push(id); + + uploaderProxy.onStatusChange(id, oldStatus, newStatus); + }, + + uuidChanged: function(id, newUuid) { + var oldUuid = data[id].uuid; + + data[id].uuid = newUuid; + byUuid[newUuid] = id; + delete byUuid[oldUuid]; + }, + + updateName: function(id, newName) { + data[id].name = newName; + }, + + updateSize: function(id, newSize) { + data[id].size = newSize; + }, + + // Only applicable if this file has a parent that we may want to reference later. + setParentId: function(targetId, parentId) { + data[targetId].parentId = parentId; + }, + + setGroupIds: function(id, groupIds) { + data[id].groupIds = groupIds; + } + }); +}; + +qq.status = { + SUBMITTING: "submitting", + SUBMITTED: "submitted", + REJECTED: "rejected", + QUEUED: "queued", + CANCELED: "canceled", + PAUSED: "paused", + UPLOADING: "uploading", + UPLOAD_RETRYING: "retrying upload", + UPLOAD_SUCCESSFUL: "upload successful", + UPLOAD_FAILED: "upload failed", + DELETE_FAILED: "delete failed", + DELETING: "deleting", + DELETED: "deleted" +}; + +/*globals qq*/ +/** + * Defines the public API for FineUploaderBasic mode. + */ +(function(){ + "use strict"; + + qq.basePublicApi = { + log: function(str, level) { + if (this._options.debug && (!level || level === "info")) { + qq.log("[Fine Uploader " + qq.version + "] " + str); + } + else if (level && level !== "info") { + qq.log("[Fine Uploader " + qq.version + "] " + str, level); + + } + }, + + setParams: function(params, id) { + this._paramsStore.set(params, id); + }, + + setDeleteFileParams: function(params, id) { + this._deleteFileParamsStore.set(params, id); + }, + + // Re-sets the default endpoint, an endpoint for a specific file, or an endpoint for a specific button + setEndpoint: function(endpoint, id) { + this._endpointStore.set(endpoint, id); + }, + + getInProgress: function() { + return this._uploadData.retrieve({ + status: [ + qq.status.UPLOADING, + qq.status.UPLOAD_RETRYING, + qq.status.QUEUED + ] + }).length; + }, + + getNetUploads: function() { + return this._netUploaded; + }, + + uploadStoredFiles: function() { + var idToUpload; + + if (this._storedIds.length === 0) { + this._itemError("noFilesError"); + } + else { + while (this._storedIds.length) { + idToUpload = this._storedIds.shift(); + this._uploadFile(idToUpload); + } + } + }, + + clearStoredFiles: function(){ + this._storedIds = []; + }, + + retry: function(id) { + return this._manualRetry(id); + }, + + cancel: function(id) { + this._handler.cancel(id); + }, + + cancelAll: function() { + var storedIdsCopy = [], + self = this; + + qq.extend(storedIdsCopy, this._storedIds); + qq.each(storedIdsCopy, function(idx, storedFileId) { + self.cancel(storedFileId); + }); + + this._handler.cancelAll(); + }, + + reset: function() { + this.log("Resetting uploader..."); + + this._handler.reset(); + this._storedIds = []; + this._autoRetries = []; + this._retryTimeouts = []; + this._preventRetries = []; + this._thumbnailUrls = []; + + qq.each(this._buttons, function(idx, button) { + button.reset(); + }); + + this._paramsStore.reset(); + this._endpointStore.reset(); + this._netUploadedOrQueued = 0; + this._netUploaded = 0; + this._uploadData.reset(); + this._buttonIdsForFileIds = []; + + this._pasteHandler && this._pasteHandler.reset(); + this._options.session.refreshOnReset && this._refreshSessionData(); + + this._succeededSinceLastAllComplete = []; + this._failedSinceLastAllComplete = []; + + this._totalProgress && this._totalProgress.reset(); + }, + + addFiles: function(filesOrInputs, params, endpoint) { + var verifiedFilesOrInputs = [], + fileOrInputIndex, fileOrInput, fileIndex; + + if (filesOrInputs) { + if (!qq.isFileList(filesOrInputs)) { + filesOrInputs = [].concat(filesOrInputs); + } + + for (fileOrInputIndex = 0; fileOrInputIndex < filesOrInputs.length; fileOrInputIndex+=1) { + fileOrInput = filesOrInputs[fileOrInputIndex]; + + if (qq.isFileOrInput(fileOrInput)) { + if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) { + for (fileIndex = 0; fileIndex < fileOrInput.files.length; fileIndex++) { + this._handleNewFile(fileOrInput.files[fileIndex], verifiedFilesOrInputs); + } + } + else { + this._handleNewFile(fileOrInput, verifiedFilesOrInputs); + } + } + else { + this.log(fileOrInput + " is not a File or INPUT element! Ignoring!", "warn"); + } + } + + this.log("Received " + verifiedFilesOrInputs.length + " files or inputs."); + this._prepareItemsForUpload(verifiedFilesOrInputs, params, endpoint); + } + }, + + addBlobs: function(blobDataOrArray, params, endpoint) { + if (!qq.supportedFeatures.blobUploading) { + throw new qq.Error("Blob uploading is not supported in this browser!"); + } + + if (blobDataOrArray) { + var blobDataArray = [].concat(blobDataOrArray), + verifiedBlobDataList = [], + self = this; + + qq.each(blobDataArray, function(idx, blobData) { + var blobOrBlobData; + + if (qq.isBlob(blobData) && !qq.isFileOrInput(blobData)) { + blobOrBlobData = { + blob: blobData, + name: self._options.blobs.defaultName + }; + } + else if (qq.isObject(blobData) && blobData.blob && blobData.name) { + blobOrBlobData = blobData; + } + else { + self.log("addBlobs: entry at index " + idx + " is not a Blob or a BlobData object", "error"); + } + + blobOrBlobData && self._handleNewFile(blobOrBlobData, verifiedBlobDataList); + }); + + this._prepareItemsForUpload(verifiedBlobDataList, params, endpoint); + } + else { + this.log("undefined or non-array parameter passed into addBlobs", "error"); + } + }, + + getUuid: function(id) { + return this._uploadData.retrieve({id: id}).uuid; + }, + + setUuid: function(id, newUuid) { + return this._uploadData.uuidChanged(id, newUuid); + }, + + getResumableFilesData: function() { + return this._handler.getResumableFilesData(); + }, + + getSize: function(id) { + return this._uploadData.retrieve({id: id}).size; + }, + + getName: function(id) { + return this._uploadData.retrieve({id: id}).name; + }, + + setName: function(id, newName) { + this._uploadData.updateName(id, newName); + }, + + getFile: function(fileOrBlobId) { + return this._handler.getFile(fileOrBlobId) || null; + }, + + deleteFile: function(id) { + return this._onSubmitDelete(id); + }, + + setDeleteFileEndpoint: function(endpoint, id) { + this._deleteFileEndpointStore.set(endpoint, id); + }, + + doesExist: function(fileOrBlobId) { + return this._handler.isValid(fileOrBlobId); + }, + + getUploads: function(optionalFilter) { + return this._uploadData.retrieve(optionalFilter); + }, + + getButton: function(fileId) { + return this._getButton(this._buttonIdsForFileIds[fileId]); + }, + + // Generate a variable size thumbnail on an img or canvas, + // returning a promise that is fulfilled when the attempt completes. + // Thumbnail can either be based off of a URL for an image returned + // by the server in the upload response, or the associated `Blob`. + drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer) { + if (this._imageGenerator) { + var fileOrUrl = this._thumbnailUrls[fileId], + options = { + scale: maxSize > 0, + maxSize: maxSize > 0 ? maxSize : null + }; + + // If client-side preview generation is possible + // and we are not specifically looking for the image URl returned by the server... + if (!fromServer && qq.supportedFeatures.imagePreviews) { + fileOrUrl = this.getFile(fileId); + } + + /* jshint eqeqeq:false,eqnull:true */ + if (fileOrUrl == null) { + return new qq.Promise().failure(imgOrCanvas, "File or URL not found."); + } + + return this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options); + } + }, + + pauseUpload: function(id) { + var uploadData = this._uploadData.retrieve({id: id}); + + if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) { + return false; + } + + // Pause only really makes sense if the file is uploading or retrying + if (qq.indexOf([qq.status.UPLOADING, qq.status.UPLOAD_RETRYING], uploadData.status) >= 0) { + if (this._handler.pause(id)) { + this._uploadData.setStatus(id, qq.status.PAUSED); + return true; + } + else { + qq.log(qq.format("Unable to pause file ID {} ({}).", id, this.getName(id)), "error"); + } + } + else { + qq.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.", id, this.getName(id)), "error"); + } + + return false; + }, + + continueUpload: function(id) { + var uploadData = this._uploadData.retrieve({id: id}); + + if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) { + return false; + } + + if (uploadData.status === qq.status.PAUSED) { + qq.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.", id, this.getName(id))); + this._uploadFile(id); + return true; + } + else { + qq.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.", id, this.getName(id)), "error"); + } + + return false; + }, + + getRemainingAllowedItems: function() { + var allowedItems = this._options.validation.itemLimit; + + if (allowedItems > 0) { + return this._options.validation.itemLimit - this._netUploadedOrQueued; + } + + return null; + }, + + scaleImage: function(id, specs) { + var self = this; + + return qq.Scaler.prototype.scaleImage(id, specs, { + log: qq.bind(self.log, self), + getFile: qq.bind(self.getFile, self), + uploadData: self._uploadData + }); + }, + + // Parent ID for a specific file, or null if this is the parent, or if it has no parent. + getParentId: function(id) { + var uploadDataEntry = this.getUploads({id: id}), + parentId = null; + + if (uploadDataEntry) { + if (uploadDataEntry.parentId !== undefined) { + parentId = uploadDataEntry.parentId; + } + } + + return parentId; + } + }; + + + + + /** + * Defines the private (internal) API for FineUploaderBasic mode. + */ + qq.basePrivateApi = { + _initFormSupportAndParams: function() { + this._formSupport = qq.FormSupport && new qq.FormSupport( + this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this) + ); + + if (this._formSupport && this._formSupport.attachedToForm) { + this._paramsStore = this._createStore( + this._options.request.params, this._formSupport.getFormInputsAsObject + ); + + this._options.autoUpload = this._formSupport.newAutoUpload; + if (this._formSupport.newEndpoint) { + this._options.request.endpoint = this._formSupport.newEndpoint; + } + } + else { + this._paramsStore = this._createStore(this._options.request.params); + } + }, + + _uploadFile: function(id) { + if (!this._handler.upload(id)) { + this._uploadData.setStatus(id, qq.status.QUEUED); + } + }, + + // Attempts to refresh session data only if the `qq.Session` module exists + // and a session endpoint has been specified. The `onSessionRequestComplete` + // callback will be invoked once the refresh is complete. + _refreshSessionData: function() { + var self = this, + options = this._options.session; + + /* jshint eqnull:true */ + if (qq.Session && this._options.session.endpoint != null) { + if (!this._session) { + qq.extend(options, this._options.cors); + + options.log = qq.bind(this.log, this); + options.addFileRecord = qq.bind(this._addCannedFile, this); + + this._session = new qq.Session(options); + } + + setTimeout(function() { + self._session.refresh().then(function(response, xhrOrXdr) { + + self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr); + + }, function(response, xhrOrXdr) { + + self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr); + }); + }, 0); + } + }, + + // Updates internal state with a file record (not backed by a live file). Returns the assigned ID. + _addCannedFile: function(sessionData) { + var id = this._uploadData.addFile(sessionData.uuid, sessionData.name, sessionData.size, + qq.status.UPLOAD_SUCCESSFUL); + + sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); + sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id); + + if (sessionData.thumbnailUrl) { + this._thumbnailUrls[id] = sessionData.thumbnailUrl; + } + + this._netUploaded++; + this._netUploadedOrQueued++; + + return id; + }, + + // Updates internal state when a new file has been received, and adds it along with its ID to a passed array. + _handleNewFile: function(file, newFileWrapperList) { + var self = this, + uuid = qq.getUniqueId(), + size = -1, + name = qq.getFilename(file), + actualFile = file.blob || file, + handler = this._customNewFileHandler ? this._customNewFileHandler : qq.bind(self._handleNewFileGeneric, self); + + if (actualFile.size >= 0) { + size = actualFile.size; + } + + handler(actualFile, name, uuid, size, newFileWrapperList, this._options.request.uuidName, { + uploadData: self._uploadData, + paramsStore: self._paramsStore, + addFileToHandler: function(id, file) { + self._handler.add(id, file); + self._netUploadedOrQueued++; + self._trackButton(id); + } + }); + }, + + _handleNewFileGeneric: function(file, name, uuid, size, fileList) { + var id = this._uploadData.addFile(uuid, name, size); + + this._handler.add(id, file); + this._trackButton(id); + + this._netUploadedOrQueued++; + + fileList.push({id: id, file: file}); + }, + + // Maps a file with the button that was used to select it. + _trackButton: function(id) { + var buttonId; + + if (qq.supportedFeatures.ajaxUploading) { + buttonId = this._handler.getFile(id).qqButtonId; + } + else { + buttonId = this._getButtonId(this._handler.getInput(id)); + } + + if (buttonId) { + this._buttonIdsForFileIds[id] = buttonId; + } + }, + + // Creates an internal object that tracks various properties of each extra button, + // and then actually creates the extra button. + _generateExtraButtonSpecs: function() { + var self = this; + + this._extraButtonSpecs = {}; + + qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) { + var multiple = extraButtonOptionEntry.multiple, + validation = qq.extend({}, self._options.validation, true), + extraButtonSpec = qq.extend({}, extraButtonOptionEntry); + + if (multiple === undefined) { + multiple = self._options.multiple; + } + + if (extraButtonSpec.validation) { + qq.extend(validation, extraButtonOptionEntry.validation, true); + } + + qq.extend(extraButtonSpec, { + multiple: multiple, + validation: validation + }, true); + + self._initExtraButton(extraButtonSpec); + }); + }, + + // Creates an extra button element + _initExtraButton: function(spec) { + var button = this._createUploadButton({ + element: spec.element, + multiple: spec.multiple, + accept: spec.validation.acceptFiles, + folders: spec.folders, + allowedExtensions: spec.validation.allowedExtensions + }); + + this._extraButtonSpecs[button.getButtonId()] = spec; + }, + + /** + * Gets the internally used tracking ID for a button. + * + * @param buttonOrFileInputOrFile `File`, ``, or a button container element + * @returns {*} The button's ID, or undefined if no ID is recoverable + * @private + */ + _getButtonId: function(buttonOrFileInputOrFile) { + var inputs, fileInput, + fileBlobOrInput = buttonOrFileInputOrFile; + + // We want the reference file/blob here if this is a proxy (a file that will be generated on-demand later) + if (fileBlobOrInput instanceof qq.BlobProxy) { + fileBlobOrInput = fileBlobOrInput.referenceBlob; + } + + // If the item is a `Blob` it will never be associated with a button or drop zone. + if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) { + if (qq.isFile(fileBlobOrInput)) { + return fileBlobOrInput.qqButtonId; + } + else if (fileBlobOrInput.tagName.toLowerCase() === "input" && + fileBlobOrInput.type.toLowerCase() === "file") { + + return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME); + } + + inputs = fileBlobOrInput.getElementsByTagName("input"); + + qq.each(inputs, function(idx, input) { + if (input.getAttribute("type") === "file") { + fileInput = input; + return false; + } + }); + + if (fileInput) { + return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME); + } + } + }, + + _annotateWithButtonId: function(file, associatedInput) { + if (qq.isFile(file)) { + file.qqButtonId = this._getButtonId(associatedInput); + } + }, + + _getButton: function(buttonId) { + var extraButtonsSpec = this._extraButtonSpecs[buttonId]; + + if (extraButtonsSpec) { + return extraButtonsSpec.element; + } + else if (buttonId === this._defaultButtonId) { + return this._options.button; + } + }, + + _handleCheckedCallback: function(details) { + var self = this, + callbackRetVal = details.callback(); + + if (callbackRetVal instanceof qq.Promise) { + this.log(details.name + " - waiting for " + details.name + " promise to be fulfilled for " + details.identifier); + return callbackRetVal.then( + function(successParam) { + self.log(details.name + " promise success for " + details.identifier); + details.onSuccess(successParam); + }, + function() { + if (details.onFailure) { + self.log(details.name + " promise failure for " + details.identifier); + details.onFailure(); + } + else { + self.log(details.name + " promise failure for " + details.identifier); + } + }); + } + + if (callbackRetVal !== false) { + details.onSuccess(callbackRetVal); + } + else { + if (details.onFailure) { + this.log(details.name + " - return value was 'false' for " + details.identifier + ". Invoking failure callback."); + details.onFailure(); + } + else { + this.log(details.name + " - return value was 'false' for " + details.identifier + ". Will not proceed."); + } + } + + return callbackRetVal; + }, + + /** + * Generate a tracked upload button. + * + * @param spec Object containing a required `element` property + * along with optional `multiple`, `accept`, and `folders`. + * @returns {qq.UploadButton} + * @private + */ + _createUploadButton: function(spec) { + var self = this, + acceptFiles = spec.accept || this._options.validation.acceptFiles, + allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions; + + function allowMultiple() { + if (qq.supportedFeatures.ajaxUploading) { + // Workaround for bug in iOS7 (see #1039) + if (qq.ios7() && self._isAllowedExtension(allowedExtensions, ".mov")) { + return false; + } + + if (spec.multiple === undefined) { + return self._options.multiple; + } + + return spec.multiple; + } + + return false; + } + + var button = new qq.UploadButton({ + element: spec.element, + folders: spec.folders, + name: this._options.request.inputName, + multiple: allowMultiple(), + acceptFiles: acceptFiles, + onChange: function(input) { + self._onInputChange(input); + }, + hoverClass: this._options.classes.buttonHover, + focusClass: this._options.classes.buttonFocus + }); + + this._disposeSupport.addDisposer(function() { + button.dispose(); + }); + + self._buttons.push(button); + + return button; + }, + + _createUploadHandler: function(additionalOptions, namespace) { + var self = this, + options = { + debug: this._options.debug, + maxConnections: this._options.maxConnections, + cors: this._options.cors, + demoMode: this._options.demoMode, + paramsStore: this._paramsStore, + endpointStore: this._endpointStore, + chunking: this._options.chunking, + resume: this._options.resume, + blobs: this._options.blobs, + log: qq.bind(self.log, self), + preventRetryParam: this._options.retry.preventRetryResponseProperty, + onProgress: function(id, name, loaded, total){ + self._onProgress(id, name, loaded, total); + self._options.callbacks.onProgress(id, name, loaded, total); + }, + onComplete: function(id, name, result, xhr) { + var status = self.getUploads({id: id}).status; + + // This is to deal with some observed cases where the XHR readyStateChange handler is + // invoked by the browser multiple times for the same XHR instance with the same state + // readyState value. Higher level: don't invoke complete-related code if we've already + // done this. + if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) { + return; + } + + var retVal = self._onComplete(id, name, result, xhr); + + // If the internal `_onComplete` handler returns a promise, don't invoke the `onComplete` callback + // until the promise has been fulfilled. + if (retVal instanceof qq.Promise) { + retVal.done(function() { + self._options.callbacks.onComplete(id, name, result, xhr); + }); + } + else { + self._options.callbacks.onComplete(id, name, result, xhr); + } + }, + onCancel: function(id, name) { + return self._handleCheckedCallback({ + name: "onCancel", + callback: qq.bind(self._options.callbacks.onCancel, self, id, name), + onSuccess: qq.bind(self._onCancel, self, id, name), + identifier: id + }); + }, + onUploadPrep: qq.bind(this._onUploadPrep, this), + onUpload: function(id, name) { + self._onUpload(id, name); + self._options.callbacks.onUpload(id, name); + }, + onUploadChunk: function(id, name, chunkData) { + self._onUploadChunk(id, chunkData); + self._options.callbacks.onUploadChunk(id, name, chunkData); + }, + onUploadChunkSuccess: function(id, chunkData, result, xhr) { + self._options.callbacks.onUploadChunkSuccess.apply(self, arguments); + }, + onResume: function(id, name, chunkData) { + return self._options.callbacks.onResume(id, name, chunkData); + }, + onAutoRetry: function(id, name, responseJSON, xhr) { + return self._onAutoRetry.apply(self, arguments); + }, + onUuidChanged: function(id, newUuid) { + self.log("Server requested UUID change from '" + self.getUuid(id) + "' to '" + newUuid + "'"); + self.setUuid(id, newUuid); + }, + getName: qq.bind(self.getName, self), + getUuid: qq.bind(self.getUuid, self), + getSize: qq.bind(self.getSize, self), + setSize: qq.bind(self._setSize, self), + getDataByUuid: function(uuid) { + return self.getUploads({uuid: uuid}); + }, + isQueued: function(id) { + var status = self.getUploads({id: id}).status; + return status === qq.status.QUEUED || + status === qq.status.SUBMITTED || + status === qq.status.UPLOAD_RETRYING || + status === qq.status.PAUSED; + }, + getIdsInGroup: function(id) { + return self.getUploads({id: id}).groupIds; + } + }; + + qq.each(this._options.request, function(prop, val) { + options[prop] = val; + }); + + if (additionalOptions) { + qq.each(additionalOptions, function(key, val) { + options[key] = val; + }); + } + + return new qq.UploadHandler(options, namespace); + }, + + _createDeleteHandler: function() { + var self = this; + + return new qq.DeleteFileAjaxRequester({ + method: this._options.deleteFile.method.toUpperCase(), + maxConnections: this._options.maxConnections, + uuidParamName: this._options.request.uuidName, + customHeaders: this._options.deleteFile.customHeaders, + paramsStore: this._deleteFileParamsStore, + endpointStore: this._deleteFileEndpointStore, + demoMode: this._options.demoMode, + cors: this._options.cors, + log: qq.bind(self.log, self), + onDelete: function(id) { + self._onDelete(id); + self._options.callbacks.onDelete(id); + }, + onDeleteComplete: function(id, xhrOrXdr, isError) { + self._onDeleteComplete(id, xhrOrXdr, isError); + self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError); + } + + }); + }, + + _createPasteHandler: function() { + var self = this; + + return new qq.PasteSupport({ + targetElement: this._options.paste.targetElement, + callbacks: { + log: qq.bind(self.log, self), + pasteReceived: function(blob) { + self._handleCheckedCallback({ + name: "onPasteReceived", + callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob), + onSuccess: qq.bind(self._handlePasteSuccess, self, blob), + identifier: "pasted image" + }); + } + } + }); + }, + + _createUploadDataTracker: function() { + var self = this; + + return new qq.UploadData({ + getName: function(id) { + return self.getName(id); + }, + getUuid: function(id) { + return self.getUuid(id); + }, + getSize: function(id) { + return self.getSize(id); + }, + onStatusChange: function(id, oldStatus, newStatus) { + self._onUploadStatusChange(id, oldStatus, newStatus); + self._options.callbacks.onStatusChange(id, oldStatus, newStatus); + self._maybeAllComplete(id, newStatus); + + if (self._totalProgress) { + setTimeout(function() { + self._totalProgress.onStatusChange(id, oldStatus, newStatus); + }, 0); + } + } + }); + }, + + _onUploadStatusChange: function(id, oldStatus, newStatus) { + // Make sure a "queued" retry attempt is canceled if the upload has been paused + if (newStatus === qq.status.PAUSED) { + clearTimeout(this._retryTimeouts[id]); + } + }, + + _handlePasteSuccess: function(blob, extSuppliedName) { + var extension = blob.type.split("/")[1], + name = extSuppliedName; + + /*jshint eqeqeq: true, eqnull: true*/ + if (name == null) { + name = this._options.paste.defaultName; + } + + name += "." + extension; + + this.addBlobs({ + name: name, + blob: blob + }); + }, + + _preventLeaveInProgress: function(){ + var self = this; + + this._disposeSupport.attach(window, "beforeunload", function(e){ + if (self.getInProgress()) { + e = e || window.event; + // for ie, ff + e.returnValue = self._options.messages.onLeave; + // for webkit + return self._options.messages.onLeave; + } + }); + }, + + _onSubmit: function(id, name) { + //nothing to do yet in core uploader + }, + + _onProgress: function(id, name, loaded, total) { + this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total); + }, + + _onTotalProgress: function(loaded, total) { + this._options.callbacks.onTotalProgress(loaded, total); + }, + + _onComplete: function(id, name, result, xhr) { + if (!result.success) { + this._netUploadedOrQueued--; + this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED); + + if (result[this._options.retry.preventRetryResponseProperty] === true) { + this._preventRetries[id] = true; + } + } + else { + if (result.thumbnailUrl) { + this._thumbnailUrls[id] = result.thumbnailUrl; + } + + this._netUploaded++; + this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL); + } + + this._maybeParseAndSendUploadError(id, name, result, xhr); + + return result.success ? true : false; + }, + + _maybeAllComplete: function(id, status) { + var self = this, + notFinished = this._getNotFinished(); + + if (status === qq.status.UPLOAD_SUCCESSFUL) { + this._succeededSinceLastAllComplete.push(id); + } + else if (status === qq.status.UPLOAD_FAILED) { + this._failedSinceLastAllComplete.push(id); + } + + if (notFinished === 0 && + (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) { + // Attempt to ensure onAllComplete is not invoked before other callbacks, such as onCancel & onComplete + setTimeout(function() { + self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete); + }, 0); + } + }, + + _getNotFinished: function() { + return this._uploadData.retrieve({ + status: [ + qq.status.UPLOADING, + qq.status.UPLOAD_RETRYING, + qq.status.QUEUED, + qq.status.SUBMITTING, + qq.status.SUBMITTED, + qq.status.PAUSED + ] + }).length; + }, + + _onAllComplete: function(successful, failed) { + this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries); + + this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed)); + + this._succeededSinceLastAllComplete = []; + this._failedSinceLastAllComplete = []; + }, + + _onCancel: function(id, name) { + this._netUploadedOrQueued--; + + clearTimeout(this._retryTimeouts[id]); + + var storedItemIndex = qq.indexOf(this._storedIds, id); + if (!this._options.autoUpload && storedItemIndex >= 0) { + this._storedIds.splice(storedItemIndex, 1); + } + + this._uploadData.setStatus(id, qq.status.CANCELED); + }, + + _isDeletePossible: function() { + if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) { + return false; + } + + if (this._options.cors.expected) { + if (qq.supportedFeatures.deleteFileCorsXhr) { + return true; + } + + if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) { + return true; + } + + return false; + } + + return true; + }, + + _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) { + var uuid = this.getUuid(id), + adjustedOnSuccessCallback; + + if (onSuccessCallback) { + adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams); + } + + if (this._isDeletePossible()) { + this._handleCheckedCallback({ + name: "onSubmitDelete", + callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id), + onSuccess: adjustedOnSuccessCallback || + qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams), + identifier: id + }); + return true; + } + else { + this.log("Delete request ignored for ID " + id + ", delete feature is disabled or request not possible " + + "due to CORS on a user agent that does not support pre-flighting.", "warn"); + return false; + } + }, + + _onDelete: function(id) { + this._uploadData.setStatus(id, qq.status.DELETING); + }, + + _onDeleteComplete: function(id, xhrOrXdr, isError) { + var name = this.getName(id); + + if (isError) { + this._uploadData.setStatus(id, qq.status.DELETE_FAILED); + this.log("Delete request for '" + name + "' has failed.", "error"); + + // For error reporing, we only have accesss to the response status if this is not + // an `XDomainRequest`. + if (xhrOrXdr.withCredentials === undefined) { + this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); + } + else { + this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); + } + } + else { + this._netUploadedOrQueued--; + this._netUploaded--; + this._handler.expunge(id); + this._uploadData.setStatus(id, qq.status.DELETED); + this.log("Delete request for '" + name + "' has succeeded."); + } + }, + + _onUploadPrep: function(id) { + // nothing to do in the core uploader for now + }, + + _onUpload: function(id, name) { + this._uploadData.setStatus(id, qq.status.UPLOADING); + }, + + _onUploadChunk: function(id, chunkData) { + //nothing to do in the base uploader + }, + + _onInputChange: function(input) { + var fileIndex; + + if (qq.supportedFeatures.ajaxUploading) { + for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) { + this._annotateWithButtonId(input.files[fileIndex], input); + } + + this.addFiles(input.files); + } + // Android 2.3.x will fire `onchange` even if no file has been selected + else if (input.value.length > 0) { + this.addFiles(input); + } + + qq.each(this._buttons, function(idx, button) { + button.reset(); + }); + }, + + _onBeforeAutoRetry: function(id, name) { + this.log("Waiting " + this._options.retry.autoAttemptDelay + " seconds before retrying " + name + "..."); + }, + + /** + * Attempt to automatically retry a failed upload. + * + * @param id The file ID of the failed upload + * @param name The name of the file associated with the failed upload + * @param responseJSON Response from the server, parsed into a javascript object + * @param xhr Ajax transport used to send the failed request + * @param callback Optional callback to be invoked if a retry is prudent. + * Invoked in lieu of asking the upload handler to retry. + * @returns {boolean} true if an auto-retry will occur + * @private + */ + _onAutoRetry: function(id, name, responseJSON, xhr, callback) { + var self = this; + + self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty]; + + if (self._shouldAutoRetry(id, name, responseJSON)) { + self._maybeParseAndSendUploadError.apply(self, arguments); + self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id] + 1); + self._onBeforeAutoRetry(id, name); + + self._retryTimeouts[id] = setTimeout(function() { + self.log("Retrying " + name + "..."); + self._autoRetries[id]++; + self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING); + + if (callback) { + callback(id); + } + else { + self._handler.retry(id); + } + }, self._options.retry.autoAttemptDelay * 1000); + + return true; + } + }, + + _shouldAutoRetry: function(id, name, responseJSON) { + var uploadData = this._uploadData.retrieve({id: id}); + + /*jshint laxbreak: true */ + if (!this._preventRetries[id] + && this._options.retry.enableAuto + && uploadData.status !== qq.status.PAUSED) { + + if (this._autoRetries[id] === undefined) { + this._autoRetries[id] = 0; + } + + return this._autoRetries[id] < this._options.retry.maxAutoAttempts; + } + + return false; + }, + + //return false if we should not attempt the requested retry + _onBeforeManualRetry: function(id) { + var itemLimit = this._options.validation.itemLimit; + + if (this._preventRetries[id]) { + this.log("Retries are forbidden for id " + id, "warn"); + return false; + } + else if (this._handler.isValid(id)) { + var fileName = this.getName(id); + + if (this._options.callbacks.onManualRetry(id, fileName) === false) { + return false; + } + + if (itemLimit > 0 && this._netUploadedOrQueued+1 > itemLimit) { + this._itemError("retryFailTooManyItems"); + return false; + } + + this.log("Retrying upload for '" + fileName + "' (id: " + id + ")..."); + return true; + } + else { + this.log("'" + id + "' is not a valid file ID", "error"); + return false; + } + }, + + /** + * Conditionally orders a manual retry of a failed upload. + * + * @param id File ID of the failed upload + * @param callback Optional callback to invoke if a retry is prudent. + * In lieu of asking the upload handler to retry. + * @returns {boolean} true if a manual retry will occur + * @private + */ + _manualRetry: function(id, callback) { + if (this._onBeforeManualRetry(id)) { + this._netUploadedOrQueued++; + this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING); + + if (callback) { + callback(id); + } + else { + this._handler.retry(id); + } + + return true; + } + }, + + _maybeParseAndSendUploadError: function(id, name, response, xhr) { + // Assuming no one will actually set the response code to something other than 200 + // and still set 'success' to true... + if (!response.success){ + if (xhr && xhr.status !== 200 && !response.error) { + this._options.callbacks.onError(id, name, "XHR returned response code " + xhr.status, xhr); + } + else { + var errorReason = response.error ? response.error : this._options.text.defaultResponseError; + this._options.callbacks.onError(id, name, errorReason, xhr); + } + } + }, + + _prepareItemsForUpload: function(items, params, endpoint) { + if (items.length === 0) { + this._itemError("noFilesError"); + return; + } + + var validationDescriptors = this._getValidationDescriptors(items), + buttonId = this._getButtonId(items[0].file), + button = this._getButton(buttonId); + + this._handleCheckedCallback({ + name: "onValidateBatch", + callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button), + onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button), + onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items), + identifier: "batch validation" + }); + }, + + _upload: function(id, params, endpoint) { + var name = this.getName(id); + + if (params) { + this.setParams(params, id); + } + + if (endpoint) { + this.setEndpoint(endpoint, id); + } + + this._handleCheckedCallback({ + name: "onSubmit", + callback: qq.bind(this._options.callbacks.onSubmit, this, id, name), + onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name), + onFailure: qq.bind(this._fileOrBlobRejected, this, id, name), + identifier: id + }); + }, + + _onSubmitCallbackSuccess: function(id, name) { + this._onSubmit.apply(this, arguments); + this._uploadData.setStatus(id, qq.status.SUBMITTED); + this._onSubmitted.apply(this, arguments); + this._options.callbacks.onSubmitted.apply(this, arguments); + + if (this._options.autoUpload) { + this._uploadFile(id); + } + else { + this._storeForLater(id); + } + }, + + _onSubmitted: function(id) { + //nothing to do in the base uploader + }, + + _storeForLater: function(id) { + this._storedIds.push(id); + }, + + _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) { + var errorMessage, + itemLimit = this._options.validation.itemLimit, + proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued; + + if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) { + if (items.length > 0) { + this._handleCheckedCallback({ + name: "onValidate", + callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button), + onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint), + onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint), + identifier: "Item '" + items[0].file.name + "', size: " + items[0].file.size + }); + } + else { + this._itemError("noFilesError"); + } + } + else { + this._onValidateBatchCallbackFailure(items); + errorMessage = this._options.messages.tooManyItemsError + .replace(/\{netItems\}/g, proposedNetFilesUploadedOrQueued) + .replace(/\{itemLimit\}/g, itemLimit); + this._batchError(errorMessage); + } + }, + + _onValidateBatchCallbackFailure: function(fileWrappers) { + var self = this; + + qq.each(fileWrappers, function(idx, fileWrapper) { + self._fileOrBlobRejected(fileWrapper.id); + }); + }, + + _onValidateCallbackSuccess: function(items, index, params, endpoint) { + var self = this, + nextIndex = index+1, + validationDescriptor = this._getValidationDescriptor(items[index]); + + this._validateFileOrBlobData(items[index], validationDescriptor) + .then( + function() { + self._upload(items[index].id, params, endpoint); + self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint); + }, + function() { + self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint); + } + ); + }, + + _onValidateCallbackFailure: function(items, index, params, endpoint) { + var nextIndex = index+ 1; + + this._fileOrBlobRejected(items[0].id, items[0].file.name); + + this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint); + }, + + _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) { + var self = this; + + if (items.length > index) { + if (validItem || !this._options.validation.stopOnFirstInvalidFile) { + //use setTimeout to prevent a stack overflow with a large number of files in the batch & non-promissory callbacks + setTimeout(function() { + var validationDescriptor = self._getValidationDescriptor(items[index]); + + self._handleCheckedCallback({ + name: "onValidate", + callback: qq.bind(self._options.callbacks.onValidate, self, items[index].file), + onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint), + onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint), + identifier: "Item '" + validationDescriptor.name + "', size: " + validationDescriptor.size + }); + }, 0); + } + else if (!validItem) { + for (; index < items.length; index++) { + self._fileOrBlobRejected(items[index].id); + } + } + } + }, + + /** + * Performs some internal validation checks on an item, defined in the `validation` option. + * + * @param fileWrapper Wrapper containing a `file` along with an `id` + * @param validationDescriptor Normalized information about the item (`size`, `name`). + * @returns qq.Promise with appropriate callbacks invoked depending on the validity of the file + * @private + */ + _validateFileOrBlobData: function(fileWrapper, validationDescriptor) { + var self = this, + file = (function() { + if (fileWrapper.file instanceof qq.BlobProxy) { + return fileWrapper.file.referenceBlob; + } + return fileWrapper.file; + }()), + name = validationDescriptor.name, + size = validationDescriptor.size, + buttonId = this._getButtonId(fileWrapper.file), + validationBase = this._getValidationBase(buttonId), + validityChecker = new qq.Promise(); + + validityChecker.then( + function() {}, + function() { + self._fileOrBlobRejected(fileWrapper.id, name); + }); + + if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) { + this._itemError("typeError", name, file); + return validityChecker.failure(); + } + + if (size === 0) { + this._itemError("emptyError", name, file); + return validityChecker.failure(); + } + + if (size && validationBase.sizeLimit && size > validationBase.sizeLimit) { + this._itemError("sizeError", name, file); + return validityChecker.failure(); + } + + if (size && size < validationBase.minSizeLimit) { + this._itemError("minSizeError", name, file); + return validityChecker.failure(); + } + + if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) { + new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then( + validityChecker.success, + function(errorCode) { + self._itemError(errorCode + "ImageError", name, file); + validityChecker.failure(); + } + ); + } + else { + validityChecker.success(); + } + + return validityChecker; + }, + + _fileOrBlobRejected: function(id) { + this._netUploadedOrQueued--; + this._uploadData.setStatus(id, qq.status.REJECTED); + }, + + /** + * Constructs and returns a message that describes an item/file error. Also calls `onError` callback. + * + * @param code REQUIRED - a code that corresponds to a stock message describing this type of error + * @param maybeNameOrNames names of the items that have failed, if applicable + * @param item `File`, `Blob`, or `` + * @private + */ + _itemError: function(code, maybeNameOrNames, item) { + var message = this._options.messages[code], + allowedExtensions = [], + names = [].concat(maybeNameOrNames), + name = names[0], + buttonId = this._getButtonId(item), + validationBase = this._getValidationBase(buttonId), + extensionsForMessage, placeholderMatch; + + function r(name, replacement){ message = message.replace(name, replacement); } + + qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) { + /** + * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the + * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details. + */ + if (qq.isString(allowedExtension)) { + allowedExtensions.push(allowedExtension); + } + }); + + extensionsForMessage = allowedExtensions.join(", ").toLowerCase(); + + r("{file}", this._options.formatFileName(name)); + r("{extensions}", extensionsForMessage); + r("{sizeLimit}", this._formatSize(validationBase.sizeLimit)); + r("{minSizeLimit}", this._formatSize(validationBase.minSizeLimit)); + + placeholderMatch = message.match(/(\{\w+\})/g); + if (placeholderMatch !== null) { + qq.each(placeholderMatch, function(idx, placeholder) { + r(placeholder, names[idx]); + }); + } + + this._options.callbacks.onError(null, name, message, undefined); + + return message; + }, + + _batchError: function(message) { + this._options.callbacks.onError(null, null, message, undefined); + }, + + _isAllowedExtension: function(allowed, fileName) { + var valid = false; + + if (!allowed.length) { + return true; + } + + qq.each(allowed, function(idx, allowedExt) { + /** + * If an argument is not a string, ignore it. Added when a possible issue with MooTools hijacking the + * `allowedExtensions` array was discovered. See case #735 in the issue tracker for more details. + */ + if (qq.isString(allowedExt)) { + /*jshint eqeqeq: true, eqnull: true*/ + var extRegex = new RegExp("\\." + allowedExt + "$", "i"); + + if (fileName.match(extRegex) != null) { + valid = true; + return false; + } + } + }); + + return valid; + }, + + _formatSize: function(bytes){ + var i = -1; + do { + bytes = bytes / 1000; + i++; + } while (bytes > 999); + + return Math.max(bytes, 0.1).toFixed(1) + this._options.text.sizeSymbols[i]; + }, + + _wrapCallbacks: function() { + var self, safeCallback; + + self = this; + + safeCallback = function(name, callback, args) { + var errorMsg; + + try { + return callback.apply(self, args); + } + catch (exception) { + errorMsg = exception.message || exception.toString(); + self.log("Caught exception in '" + name + "' callback - " + errorMsg, "error"); + } + }; + + /* jshint forin: false, loopfunc: true */ + for (var prop in this._options.callbacks) { + (function() { + var callbackName, callbackFunc; + callbackName = prop; + callbackFunc = self._options.callbacks[callbackName]; + self._options.callbacks[callbackName] = function() { + return safeCallback(callbackName, callbackFunc, arguments); + }; + }()); + } + }, + + _getValidationDescriptors: function(fileWrappers) { + var self = this, + fileDescriptors = []; + + qq.each(fileWrappers, function(idx, fileWrapper) { + fileDescriptors.push(self._getValidationDescriptor(fileWrapper)); + }); + + return fileDescriptors; + }, + + _getValidationDescriptor: function(fileWrapper) { + if (fileWrapper.file instanceof qq.BlobProxy) { + return { + name: qq.getFilename(fileWrapper.file.referenceBlob), + size: fileWrapper.file.referenceBlob.size + }; + } + + return { + name: this.getUploads({id: fileWrapper.id}).name, + size: this.getUploads({id: fileWrapper.id}).size + }; + }, + + _createStore: function(initialValue, readOnlyValues) { + var store = {}, + catchall = initialValue, + perIdReadOnlyValues = {}, + copy = function(orig) { + if (qq.isObject(orig)) { + return qq.extend({}, orig); + } + return orig; + }, + getReadOnlyValues = function() { + if (qq.isFunction(readOnlyValues)) { + return readOnlyValues(); + } + return readOnlyValues; + }, + includeReadOnlyValues = function(id, existing) { + if (readOnlyValues && qq.isObject(existing)) { + qq.extend(existing, getReadOnlyValues()); + } + + if (perIdReadOnlyValues[id]) { + qq.extend(existing, perIdReadOnlyValues[id]); + } + }; + + return { + set: function(val, id) { + /*jshint eqeqeq: true, eqnull: true*/ + if (id == null) { + store = {}; + catchall = copy(val); + } + else { + store[id] = copy(val); + } + }, + + get: function(id) { + var values; + + /*jshint eqeqeq: true, eqnull: true*/ + if (id != null && store[id]) { + values = store[id]; + } + else { + values = copy(catchall); + } + + includeReadOnlyValues(id, values); + + return copy(values); + }, + + addReadOnly: function(id, values) { + // Only applicable to Object stores + if (qq.isObject(store)) { + perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {}; + qq.extend(perIdReadOnlyValues[id], values); + } + }, + + remove: function(fileId) { + return delete store[fileId]; + }, + + reset: function() { + store = {}; + perIdReadOnlyValues = {}; + catchall = initialValue; + } + }; + }, + + // Allows camera access on either the default or an extra button for iOS devices. + _handleCameraAccess: function() { + if (this._options.camera.ios && qq.ios()) { + var acceptIosCamera = "image/*;capture=camera", + button = this._options.camera.button, + buttonId = button ? this._getButtonId(button) : this._defaultButtonId, + optionRoot = this._options; + + // If we are not targeting the default button, it is an "extra" button + if (buttonId && buttonId !== this._defaultButtonId) { + optionRoot = this._extraButtonSpecs[buttonId]; + } + + // Camera access won't work in iOS if the `multiple` attribute is present on the file input + optionRoot.multiple = false; + + // update the options + if (optionRoot.validation.acceptFiles === null) { + optionRoot.validation.acceptFiles = acceptIosCamera; + } + else { + optionRoot.validation.acceptFiles += "," + acceptIosCamera; + } + + // update the already-created button + qq.each(this._buttons, function(idx, button) { + if (button.getButtonId() === buttonId) { + button.setMultiple(optionRoot.multiple); + button.setAcceptFiles(optionRoot.acceptFiles); + + return false; + } + }); + } + }, + + // Get the validation options for this button. Could be the default validation option + // or a specific one assigned to this particular button. + _getValidationBase: function(buttonId) { + var extraButtonSpec = this._extraButtonSpecs[buttonId]; + + return extraButtonSpec ? extraButtonSpec.validation : this._options.validation; + }, + + _setSize: function(id, newSize) { + this._uploadData.updateSize(id, newSize); + this._totalProgress && this._totalProgress.onNewSize(id); + } + }; +}()); + +/*globals qq*/ +(function(){ + "use strict"; + + qq.FineUploaderBasic = function(o) { + var self = this; + + // These options define FineUploaderBasic mode. + this._options = { + debug: false, + button: null, + multiple: true, + maxConnections: 3, + disableCancelForFormUploads: false, + autoUpload: true, + + request: { + endpoint: "/server/upload", + params: {}, + paramsInBody: true, + customHeaders: {}, + forceMultipart: true, + inputName: "qqfile", + uuidName: "qquuid", + totalFileSizeName: "qqtotalfilesize", + filenameParam: "qqfilename" + }, + + validation: { + allowedExtensions: [], + sizeLimit: 0, + minSizeLimit: 0, + itemLimit: 0, + stopOnFirstInvalidFile: true, + acceptFiles: null, + image: { + maxHeight: 0, + maxWidth: 0, + minHeight: 0, + minWidth: 0 + } + }, + + callbacks: { + onSubmit: function(id, name){}, + onSubmitted: function(id, name){}, + onComplete: function(id, name, responseJSON, maybeXhr){}, + onAllComplete: function(successful, failed) {}, + onCancel: function(id, name){}, + onUpload: function(id, name){}, + onUploadChunk: function(id, name, chunkData){}, + onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr){}, + onResume: function(id, fileName, chunkData){}, + onProgress: function(id, name, loaded, total){}, + onTotalProgress: function(loaded, total){}, + onError: function(id, name, reason, maybeXhrOrXdr) {}, + onAutoRetry: function(id, name, attemptNumber) {}, + onManualRetry: function(id, name) {}, + onValidateBatch: function(fileOrBlobData) {}, + onValidate: function(fileOrBlobData) {}, + onSubmitDelete: function(id) {}, + onDelete: function(id){}, + onDeleteComplete: function(id, xhrOrXdr, isError){}, + onPasteReceived: function(blob) {}, + onStatusChange: function(id, oldStatus, newStatus) {}, + onSessionRequestComplete: function(response, success, xhrOrXdr) {} + }, + + messages: { + typeError: "{file} has an invalid extension. Valid extension(s): {extensions}.", + sizeError: "{file} is too large, maximum file size is {sizeLimit}.", + minSizeError: "{file} is too small, minimum file size is {minSizeLimit}.", + emptyError: "{file} is empty, please select files again without it.", + noFilesError: "No files to upload.", + tooManyItemsError: "Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.", + maxHeightImageError: "Image is too tall.", + maxWidthImageError: "Image is too wide.", + minHeightImageError: "Image is not tall enough.", + minWidthImageError: "Image is not wide enough.", + retryFailTooManyItems: "Retry failed - you have reached your file limit.", + onLeave: "The files are being uploaded, if you leave now the upload will be canceled." + }, + + retry: { + enableAuto: false, + maxAutoAttempts: 3, + autoAttemptDelay: 5, + preventRetryResponseProperty: "preventRetry" + }, + + classes: { + buttonHover: "qq-upload-button-hover", + buttonFocus: "qq-upload-button-focus" + }, + + chunking: { + enabled: false, + partSize: 2000000, + paramNames: { + partIndex: "qqpartindex", + partByteOffset: "qqpartbyteoffset", + chunkSize: "qqchunksize", + totalFileSize: "qqtotalfilesize", + totalParts: "qqtotalparts" + } + }, + + resume: { + enabled: false, + id: null, + cookiesExpireIn: 7, //days + paramNames: { + resuming: "qqresume" + } + }, + + formatFileName: function(fileOrBlobName) { + if (fileOrBlobName !== undefined && fileOrBlobName.length > 33) { + fileOrBlobName = fileOrBlobName.slice(0, 19) + "..." + fileOrBlobName.slice(-14); + } + return fileOrBlobName; + }, + + text: { + defaultResponseError: "Upload failure reason unknown", + sizeSymbols: ["kB", "MB", "GB", "TB", "PB", "EB"] + }, + + deleteFile : { + enabled: false, + method: "DELETE", + endpoint: "/server/upload", + customHeaders: {}, + params: {} + }, + + cors: { + expected: false, + sendCredentials: false, + allowXdr: false + }, + + blobs: { + defaultName: "misc_data" + }, + + paste: { + targetElement: null, + defaultName: "pasted_image" + }, + + camera: { + ios: false, + + // if ios is true: button is null means target the default button, otherwise target the button specified + button: null + }, + + // This refers to additional upload buttons to be handled by Fine Uploader. + // Each element is an object, containing `element` as the only required + // property. The `element` must be a container that will ultimately + // contain an invisible `` created by Fine Uploader. + // Optional properties of each object include `multiple`, `validation`, + // and `folders`. + extraButtons: [], + + // Depends on the session module. Used to query the server for an initial file list + // during initialization and optionally after a `reset`. + session: { + endpoint: null, + params: {}, + customHeaders: {}, + refreshOnReset: true + }, + + // Send parameters associated with an existing form along with the files + form: { + // Element ID, HTMLElement, or null + element: "qq-form", + + // Overrides the base `autoUpload`, unless `element` is null. + autoUpload: false, + + // true = upload files on form submission (and squelch submit event) + interceptSubmit: true + }, + + // scale images client side, upload a new file for each scaled version + scaling: { + // send the original file as well + sendOriginal: true, + + // fox orientation for scaled images + orient: true, + + // If null, scaled image type will match reference image type. This value will be referred to + // for any size record that does not specific a type. + defaultType: null, + + defaultQuality: 80, + + failureText: "Failed to scale", + + includeExif: false, + + // metadata about each requested scaled version + sizes: [] + } + }; + + // Replace any default options with user defined ones + qq.extend(this._options, o, true); + + this._buttons = []; + this._extraButtonSpecs = {}; + this._buttonIdsForFileIds = []; + + this._wrapCallbacks(); + this._disposeSupport = new qq.DisposeSupport(); + + this._storedIds = []; + this._autoRetries = []; + this._retryTimeouts = []; + this._preventRetries = []; + this._thumbnailUrls = []; + + this._netUploadedOrQueued = 0; + this._netUploaded = 0; + this._uploadData = this._createUploadDataTracker(); + + this._initFormSupportAndParams(); + + this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params); + + this._endpointStore = this._createStore(this._options.request.endpoint); + this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint); + + this._handler = this._createUploadHandler(); + + this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler(); + + if (this._options.button) { + this._defaultButtonId = this._createUploadButton({element: this._options.button}).getButtonId(); + } + + this._generateExtraButtonSpecs(); + + this._handleCameraAccess(); + + if (this._options.paste.targetElement) { + if (qq.PasteSupport) { + this._pasteHandler = this._createPasteHandler(); + } + else { + qq.log("Paste support module not found", "info"); + } + } + + this._preventLeaveInProgress(); + + this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this)); + this._refreshSessionData(); + + this._succeededSinceLastAllComplete = []; + this._failedSinceLastAllComplete = []; + + this._scaler = (qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this))) || {}; + if (this._scaler.enabled) { + this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler); + } + + if (qq.TotalProgress && qq.supportedFeatures.progressBar) { + this._totalProgress = new qq.TotalProgress( + qq.bind(this._onTotalProgress, this), + + function(id) { + var entry = self._uploadData.retrieve({id: id}); + return (entry && entry.size) || 0; + } + ); + } + }; + + // Define the private & public API methods. + qq.FineUploaderBasic.prototype = qq.basePublicApi; + qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi); +}()); + +/*globals qq, XDomainRequest*/ +/** Generic class for sending non-upload ajax requests and handling the associated responses **/ +qq.AjaxRequester = function (o) { + "use strict"; + + var log, shouldParamsBeInQueryString, + queue = [], + requestData = {}, + options = { + validMethods: ["POST"], + method: "POST", + contentType: "application/x-www-form-urlencoded", + maxConnections: 3, + customHeaders: {}, + endpointStore: {}, + paramsStore: {}, + mandatedParams: {}, + allowXRequestedWithAndCacheControl: true, + successfulResponseCodes: { + "DELETE": [200, 202, 204], + "POST": [200, 204], + "GET": [200] + }, + cors: { + expected: false, + sendCredentials: false + }, + log: function (str, level) {}, + onSend: function (id) {}, + onComplete: function (id, xhrOrXdr, isError) {}, + onProgress: null + }; + + qq.extend(options, o); + log = options.log; + + if (qq.indexOf(options.validMethods, options.method) < 0) { + throw new Error("'" + options.method + "' is not a supported method for this type of request!"); + } + + // [Simple methods](http://www.w3.org/TR/cors/#simple-method) + // are defined by the W3C in the CORS spec as a list of methods that, in part, + // make a CORS request eligible to be exempt from preflighting. + function isSimpleMethod() { + return qq.indexOf(["GET", "POST", "HEAD"], options.method) >= 0; + } + + // [Simple headers](http://www.w3.org/TR/cors/#simple-header) + // are defined by the W3C in the CORS spec as a list of headers that, in part, + // make a CORS request eligible to be exempt from preflighting. + function containsNonSimpleHeaders(headers) { + var containsNonSimple = false; + + qq.each(containsNonSimple, function(idx, header) { + if (qq.indexOf(["Accept", "Accept-Language", "Content-Language", "Content-Type"], header) < 0) { + containsNonSimple = true; + return false; + } + }); + + return containsNonSimple; + } + + function isXdr(xhr) { + //The `withCredentials` test is a commonly accepted way to determine if XHR supports CORS. + return options.cors.expected && xhr.withCredentials === undefined; + } + + // Returns either a new `XMLHttpRequest` or `XDomainRequest` instance. + function getCorsAjaxTransport() { + var xhrOrXdr; + + if (window.XMLHttpRequest || window.ActiveXObject) { + xhrOrXdr = qq.createXhrInstance(); + + if (xhrOrXdr.withCredentials === undefined) { + xhrOrXdr = new XDomainRequest(); + } + } + + return xhrOrXdr; + } + + // Returns either a new XHR/XDR instance, or an existing one for the associated `File` or `Blob`. + function getXhrOrXdr(id, dontCreateIfNotExist) { + var xhrOrXdr = requestData[id].xhr; + + if (!xhrOrXdr && !dontCreateIfNotExist) { + if (options.cors.expected) { + xhrOrXdr = getCorsAjaxTransport(); + } + else { + xhrOrXdr = qq.createXhrInstance(); + } + + requestData[id].xhr = xhrOrXdr; + } + + return xhrOrXdr; + } + + // Removes element from queue, sends next request + function dequeue(id) { + var i = qq.indexOf(queue, id), + max = options.maxConnections, + nextId; + + delete requestData[id]; + queue.splice(i, 1); + + if (queue.length >= max && i < max) { + nextId = queue[max - 1]; + sendRequest(nextId); + } + } + + function onComplete(id, xdrError) { + var xhr = getXhrOrXdr(id), + method = options.method, + isError = xdrError === true; + + dequeue(id); + + if (isError) { + log(method + " request for " + id + " has failed", "error"); + } + else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) { + isError = true; + log(method + " request for " + id + " has failed - response code " + xhr.status, "error"); + } + + options.onComplete(id, xhr, isError); + } + + function getParams(id) { + var onDemandParams = requestData[id].additionalParams, + mandatedParams = options.mandatedParams, + params; + + if (options.paramsStore.get) { + params = options.paramsStore.get(id); + } + + if (onDemandParams) { + qq.each(onDemandParams, function (name, val) { + params = params || {}; + params[name] = val; + }); + } + + if (mandatedParams) { + qq.each(mandatedParams, function (name, val) { + params = params || {}; + params[name] = val; + }); + } + + return params; + } + + function sendRequest(id) { + var xhr = getXhrOrXdr(id), + method = options.method, + params = getParams(id), + payload = requestData[id].payload, + url; + + options.onSend(id); + + url = createUrl(id, params); + + // XDR and XHR status detection APIs differ a bit. + if (isXdr(xhr)) { + xhr.onload = getXdrLoadHandler(id); + xhr.onerror = getXdrErrorHandler(id); + } + else { + xhr.onreadystatechange = getXhrReadyStateChangeHandler(id); + } + + + registerForUploadProgress(id); + + // The last parameter is assumed to be ignored if we are actually using `XDomainRequest`. + xhr.open(method, url, true); + + // Instruct the transport to send cookies along with the CORS request, + // unless we are using `XDomainRequest`, which is not capable of this. + if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) { + xhr.withCredentials = true; + } + + setHeaders(id); + + log("Sending " + method + " request for " + id); + + if (payload) { + xhr.send(payload); + } + else if (shouldParamsBeInQueryString || !params) { + xhr.send(); + } + else if (params && options.contentType && options.contentType.toLowerCase().indexOf("application/x-www-form-urlencoded") >= 0) { + xhr.send(qq.obj2url(params, "")); + } + else if (params && options.contentType && options.contentType.toLowerCase().indexOf("application/json") >= 0) { + xhr.send(JSON.stringify(params)); + } + else { + xhr.send(params); + } + + return xhr; + } + + function createUrl(id, params) { + var endpoint = options.endpointStore.get(id), + addToPath = requestData[id].addToPath; + + /*jshint -W116,-W041 */ + if (addToPath != undefined) { + endpoint += "/" + addToPath; + } + + if (shouldParamsBeInQueryString && params) { + return qq.obj2url(params, endpoint); + } + else { + return endpoint; + } + } + + // Invoked by the UA to indicate a number of possible states that describe + // a live `XMLHttpRequest` transport. + function getXhrReadyStateChangeHandler(id) { + return function () { + if (getXhrOrXdr(id).readyState === 4) { + onComplete(id); + } + }; + } + + function registerForUploadProgress(id) { + var onProgress = options.onProgress; + + if (onProgress) { + getXhrOrXdr(id).upload.onprogress = function(e) { + if (e.lengthComputable) { + onProgress(id, e.loaded, e.total); + } + }; + } + } + + // This will be called by IE to indicate **success** for an associated + // `XDomainRequest` transported request. + function getXdrLoadHandler(id) { + return function () { + onComplete(id); + }; + } + + // This will be called by IE to indicate **failure** for an associated + // `XDomainRequest` transported request. + function getXdrErrorHandler(id) { + return function () { + onComplete(id, true); + }; + } + + function setHeaders(id) { + var xhr = getXhrOrXdr(id), + customHeaders = options.customHeaders, + onDemandHeaders = requestData[id].additionalHeaders || {}, + method = options.method, + allHeaders = {}; + + // If XDomainRequest is being used, we can't set headers, so just ignore this block. + if (!isXdr(xhr)) { + // Only attempt to add X-Requested-With & Cache-Control if permitted + if (options.allowXRequestedWithAndCacheControl) { + // Do not add X-Requested-With & Cache-Control if this is a cross-origin request + // OR the cross-origin request contains a non-simple method or header. + // This is done to ensure a preflight is not triggered exclusively based on the + // addition of these 2 non-simple headers. + if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) { + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + xhr.setRequestHeader("Cache-Control", "no-cache"); + } + } + + if (options.contentType && (method === "POST" || method === "PUT")) { + xhr.setRequestHeader("Content-Type", options.contentType); + } + + qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders); + qq.extend(allHeaders, onDemandHeaders); + + qq.each(allHeaders, function (name, val) { + xhr.setRequestHeader(name, val); + }); + } + } + + function isResponseSuccessful(responseCode) { + return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0; + } + + function prepareToSend(id, addToPath, additionalParams, additionalHeaders, payload) { + requestData[id] = { + addToPath: addToPath, + additionalParams: additionalParams, + additionalHeaders: additionalHeaders, + payload: payload + }; + + var len = queue.push(id); + + // if too many active connections, wait... + if (len <= options.maxConnections) { + return sendRequest(id); + } + } + + + shouldParamsBeInQueryString = options.method === "GET" || options.method === "DELETE"; + + qq.extend(this, { + // Start the process of sending the request. The ID refers to the file associated with the request. + initTransport: function(id) { + var path, params, headers, payload, cacheBuster; + + return { + // Optionally specify the end of the endpoint path for the request. + withPath: function(appendToPath) { + path = appendToPath; + return this; + }, + + // Optionally specify additional parameters to send along with the request. + // These will be added to the query string for GET/DELETE requests or the payload + // for POST/PUT requests. The Content-Type of the request will be used to determine + // how these parameters should be formatted as well. + withParams: function(additionalParams) { + params = additionalParams; + return this; + }, + + // Optionally specify additional headers to send along with the request. + withHeaders: function(additionalHeaders) { + headers = additionalHeaders; + return this; + }, + + // Optionally specify a payload/body for the request. + withPayload: function(thePayload) { + payload = thePayload; + return this; + }, + + // Appends a cache buster (timestamp) to the request URL as a query parameter (only if GET or DELETE) + withCacheBuster: function() { + cacheBuster = true; + return this; + }, + + // Send the constructed request. + send: function() { + if (cacheBuster && qq.indexOf(["GET", "DELETE"], options.method) >= 0) { + params.qqtimestamp = new Date().getTime(); + } + + return prepareToSend(id, path, params, headers, payload); + } + }; + }, + + canceled: function(id) { + dequeue(id); + } + }); +}; + +/*globals qq*/ +/** + * Base upload handler module. Delegates to more specific handlers. + * + * @param o Options. Passed along to the specific handler submodule as well. + * @param namespace [optional] Namespace for the specific handler. + */ +qq.UploadHandler = function(o, namespace) { + "use strict"; + + var queue = [], + preventRetryResponse, options, log, handlerImpl; + + // Default options, can be overridden by the user + options = { + debug: false, + forceMultipart: true, + paramsInBody: false, + paramsStore: {}, + endpointStore: {}, + filenameParam: "qqfilename", + cors: { + expected: false, + sendCredentials: false + }, + maxConnections: 3, // maximum number of concurrent uploads + uuidName: "qquuid", + totalFileSizeName: "qqtotalfilesize", + chunking: { + enabled: false, + partSize: 2000000, //bytes + paramNames: { + partIndex: "qqpartindex", + partByteOffset: "qqpartbyteoffset", + chunkSize: "qqchunksize", + totalParts: "qqtotalparts", + filename: "qqfilename" + } + }, + resume: { + enabled: false, + id: null, + cookiesExpireIn: 7, //days + paramNames: { + resuming: "qqresume" + } + }, + log: function(str, level) {}, + onProgress: function(id, fileName, loaded, total){}, + onComplete: function(id, fileName, response, xhr){}, + onCancel: function(id, fileName){}, + onUploadPrep: function(id){}, // Called if non-trivial operations will be performed before onUpload + onUpload: function(id, fileName){}, + onUploadChunk: function(id, fileName, chunkData){}, + onUploadChunkSuccess: function(id, chunkData, response, xhr){}, + onAutoRetry: function(id, fileName, response, xhr){}, + onResume: function(id, fileName, chunkData){}, + onUuidChanged: function(id, newUuid){}, + getName: function(id) {}, + setSize: function(id, newSize) {}, + isQueued: function(id) {}, + getIdsInGroup: function(id) {} + }; + qq.extend(options, o); + + preventRetryResponse = (function() { + var response = {}; + + response[options.preventRetryParam] = true; + + return response; + }()); + + log = options.log; + + // Returns a qq.BlobProxy, or an actual File/Blob if no proxy is involved, or undefined + // if none of these are available for the ID + function getProxyOrBlob(id) { + return (handlerImpl.getProxy && handlerImpl.getProxy(id)) || + (handlerImpl.getFile && handlerImpl.getFile(id)); + } + + // Used when determining if a grouped Blob should be uploaded + function waitingAndReadyForUpload(id) { + return !!handlerImpl.getFile(id); + } + + // Used when determining if a grouped Blob should be uploaded + function eligibleForUpload(id) { + return options.isQueued(id); + } + + // Upload any grouped blobs, in the proper order, that are ready to be uploaded + function maybeReadyToUpload(id) { + var idsInGroup = options.getIdsInGroup(id), + uploadedThisId = false; + + if (idsInGroup && idsInGroup.length) { + log("Maybe ready to upload grouped file " + id); + + qq.each(idsInGroup, function(idx, idInGroup) { + if (eligibleForUpload(idInGroup) && waitingAndReadyForUpload(idInGroup)) { + uploadedThisId = idInGroup === id; + handlerImpl.upload(idInGroup); + } + else if (eligibleForUpload(idInGroup)) { + return false; + } + }); + } + else { + uploadedThisId = true; + handlerImpl.upload(id); + } + + return uploadedThisId; + } + + // For Blobs that are part of a group of generated images, along with a reference image, + // this will ensure the blobs in the group are uploaded in the order they were triggered, + // even if some async processing must be completed on one or more Blobs first. + function startBlobUpload(id, blob) { + // If we don't have a file/blob yet & no file/blob exists for this item, request it, + // and then submit the upload to the specific handler once the blob is available. + // ASSUMPTION: This condition will only ever be true if XHR uploading is supported. + if (blob && !handlerImpl.getFile(id) && blob instanceof qq.BlobProxy) { + + // Blob creation may take some time, so the caller may want to update the + // UI to indicate that an operation is in progress, even before the actual + // upload begins and an onUpload callback is invoked. + options.onUploadPrep(id); + + log("Attempting to generate a blob on-demand for " + id); + blob.create().then(function(generatedBlob) { + log("Generated an on-demand blob for " + id); + + // Update record associated with this file by providing the generated Blob + handlerImpl.updateBlob(id, generatedBlob); + + // Propagate the size for this generated Blob + options.setSize(id, generatedBlob.size); + + // Order handler to recalculate chunking possibility, if applicable + handlerImpl.reevaluateChunking(id); + + maybeReadyToUpload(id); + }, + + // Blob could not be generated. Fail the upload & attempt to prevent retries. Also bubble error message. + function(errorMessage) { + var errorResponse = {}; + + if (errorMessage) { + errorResponse.error = errorMessage; + } + + log(qq.format("Failed to generate scaled version for ID {}. Error message: {}.", id, errorMessage), "error"); + + options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null); + maybeReadyToUpload(id); + dequeue(id); + }); + } + else { + return maybeReadyToUpload(id); + } + + return false; + } + + // Called whenever a file is to be uploaded. Returns true if the file will be uploaded at once. + function startUpload(id) { + var blobToUpload = getProxyOrBlob(id); + + if (blobToUpload) { + return startBlobUpload(id, blobToUpload); + } + else { + handlerImpl.upload(id); + return true; + } + + } + + /** + * Removes element from queue, starts upload of next + */ + function dequeue(id) { + var i = qq.indexOf(queue, id), + max = options.maxConnections, + nextId; + + if (getProxyOrBlob(id) instanceof qq.BlobProxy) { + log("Generated blob upload has ended for " + id + ", disposing generated blob."); + delete handlerImpl._getFileState(id).file; + } + + if (i >= 0) { + queue.splice(i, 1); + + if (queue.length >= max && i < max) { + nextId = queue[max-1]; + startUpload(nextId); + } + } + } + + function cancelSuccess(id) { + log("Cancelling " + id); + options.paramsStore.remove(id); + dequeue(id); + } + + function determineHandlerImpl() { + var handlerType = namespace ? qq[namespace] : qq, + handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? "Xhr" : "Form"; + + handlerImpl = new handlerType["UploadHandler" + handlerModuleSubtype]( + options, + { + onUploadComplete: dequeue, + onUuidChanged: options.onUuidChanged, + getName: options.getName, + getUuid: options.getUuid, + getSize: options.getSize, + getDataByUuid: options.getDataByUuid, + log: log + } + ); + } + + + qq.extend(this, { + /** + * Adds file or file input to the queue + * @returns id + **/ + add: function(id, file) { + return handlerImpl.add.apply(this, arguments); + }, + + /** + * Sends the file identified by id + */ + upload: function(id) { + var len = queue.push(id); + + // if too many active uploads, wait... + if (len <= options.maxConnections) { + return startUpload(id); + } + + return false; + }, + + retry: function(id) { + var i = qq.indexOf(queue, id), + blobOrProxy = getProxyOrBlob(id), + isProxy = blobOrProxy && blobOrProxy instanceof qq.BlobProxy; + + if (i >= 0) { + return isProxy ? startUpload(id) : handlerImpl.upload(id, true); + } + else { + return this.upload(id); + } + }, + + /** + * Cancels file upload by id + */ + cancel: function(id) { + var cancelRetVal = handlerImpl.cancel(id); + + if (cancelRetVal instanceof qq.Promise) { + cancelRetVal.then(function() { + cancelSuccess(id); + }); + } + else if (cancelRetVal !== false) { + cancelSuccess(id); + } + }, + + /** + * Cancels all queued or in-progress uploads + */ + cancelAll: function() { + var self = this, + queueCopy = []; + + qq.extend(queueCopy, queue); + qq.each(queueCopy, function(idx, fileId) { + self.cancel(fileId); + }); + + queue = []; + }, + + // Returns a File, Blob, or the Blob/File for the reference/parent file if the targeted blob is a proxy. + // Undefined if no file record is available. + getFile: function(id) { + if (handlerImpl.getProxy && handlerImpl.getProxy(id)) { + return handlerImpl.getProxy(id).referenceBlob; + } + + return handlerImpl.getFile && handlerImpl.getFile(id); + }, + + // Returns true if the Blob associated with the ID is related to a proxy s + isProxied: function(id) { + return !!(handlerImpl.getProxy && handlerImpl.getProxy(id)); + }, + + getInput: function(id) { + if (handlerImpl.getInput) { + return handlerImpl.getInput(id); + } + }, + + reset: function() { + log("Resetting upload handler"); + this.cancelAll(); + queue = []; + handlerImpl.reset(); + }, + + expunge: function(id) { + if (this.isValid(id)) { + return handlerImpl.expunge(id); + } + }, + + /** + * Determine if the file exists. + */ + isValid: function(id) { + return handlerImpl.isValid(id); + }, + + getResumableFilesData: function() { + if (handlerImpl.getResumableFilesData) { + return handlerImpl.getResumableFilesData(); + } + return []; + }, + + /** + * This may or may not be implemented, depending on the handler. For handlers where a third-party ID is + * available (such as the "key" for Amazon S3), this will return that value. Otherwise, the return value + * will be undefined. + * + * @param id Internal file ID + * @returns {*} Some identifier used by a 3rd-party service involved in the upload process + */ + getThirdPartyFileId: function(id) { + if (handlerImpl.getThirdPartyFileId && this.isValid(id)) { + return handlerImpl.getThirdPartyFileId(id); + } + }, + + /** + * Attempts to pause the associated upload if the specific handler supports this and the file is "valid". + * @param id ID of the upload/file to pause + * @returns {boolean} true if the upload was paused + */ + pause: function(id) { + if (this.isResumable(id) && handlerImpl.pause && this.isValid(id) && handlerImpl.pause(id)) { + dequeue(id); + return true; + } + }, + + // True if the file is eligible for pause/resume. + isResumable: function(id) { + return !!handlerImpl.isResumable && handlerImpl.isResumable(id); + } + }); + + determineHandlerImpl(); +}; + +/* globals qq */ +/** + * Common APIs exposed to creators of upload via form/iframe handlers. This is reused and possibly overridden + * in some cases by specific form upload handlers. + * + * @constructor + */ +qq.AbstractUploadHandlerForm = function(spec) { + "use strict"; + + var options = spec.options, + handler = this, + proxy = spec.proxy, + formHandlerInstanceId = qq.getUniqueId(), + onloadCallbacks = {}, + detachLoadEvents = {}, + postMessageCallbackTimers = {}, + isCors = options.isCors, + fileState = {}, + inputName = options.inputName, + onCancel = proxy.onCancel, + onUuidChanged = proxy.onUuidChanged, + getName = proxy.getName, + getUuid = proxy.getUuid, + log = proxy.log, + corsMessageReceiver = new qq.WindowReceiveMessage({log: log}); + + + /** + * Remove any trace of the file from the handler. + * + * @param id ID of the associated file + */ + function expungeFile(id) { + delete detachLoadEvents[id]; + delete fileState[id]; + + // If we are dealing with CORS, we might still be waiting for a response from a loaded iframe. + // In that case, terminate the timer waiting for a message from the loaded iframe + // and stop listening for any more messages coming from this iframe. + if (isCors) { + clearTimeout(postMessageCallbackTimers[id]); + delete postMessageCallbackTimers[id]; + corsMessageReceiver.stopReceivingMessages(id); + } + + var iframe = document.getElementById(handler._getIframeName(id)); + if (iframe) { + // To cancel request set src to something else. We use src="javascript:false;" + // because it doesn't trigger ie6 prompt on https + iframe.setAttribute("src", "java" + String.fromCharCode(115) + "cript:false;"); //deal with "JSLint: javascript URL" warning, which apparently cannot be turned off + + qq(iframe).remove(); + } + } + + /** + * If we are in CORS mode, we must listen for messages (containing the server response) from the associated + * iframe, since we cannot directly parse the content of the iframe due to cross-origin restrictions. + * + * @param iframe Listen for messages on this iframe. + * @param callback Invoke this callback with the message from the iframe. + */ + function registerPostMessageCallback(iframe, callback) { + var iframeName = iframe.id, + fileId = getFileIdForIframeName(iframeName), + uuid = getUuid(fileId); + + onloadCallbacks[uuid] = callback; + + // When the iframe has loaded (after the server responds to an upload request) + // declare the attempt a failure if we don't receive a valid message shortly after the response comes in. + detachLoadEvents[fileId] = qq(iframe).attach("load", function() { + if (fileState[fileId].input) { + log("Received iframe load event for CORS upload request (iframe name " + iframeName + ")"); + + postMessageCallbackTimers[iframeName] = setTimeout(function() { + var errorMessage = "No valid message received from loaded iframe for iframe name " + iframeName; + log(errorMessage, "error"); + callback({ + error: errorMessage + }); + }, 1000); + } + }); + + // Listen for messages coming from this iframe. When a message has been received, cancel the timer + // that declares the upload a failure if a message is not received within a reasonable amount of time. + corsMessageReceiver.receiveMessage(iframeName, function(message) { + log("Received the following window message: '" + message + "'"); + var fileId = getFileIdForIframeName(iframeName), + response = handler._parseJsonResponse(fileId, message), + uuid = response.uuid, + onloadCallback; + + if (uuid && onloadCallbacks[uuid]) { + log("Handling response for iframe name " + iframeName); + clearTimeout(postMessageCallbackTimers[iframeName]); + delete postMessageCallbackTimers[iframeName]; + + handler._detachLoadEvent(iframeName); + + onloadCallback = onloadCallbacks[uuid]; + + delete onloadCallbacks[uuid]; + corsMessageReceiver.stopReceivingMessages(iframeName); + onloadCallback(response); + } + else if (!uuid) { + log("'" + message + "' does not contain a UUID - ignoring."); + } + }); + } + + /** + * Generates an iframe to be used as a target for upload-related form submits. This also adds the iframe + * to the current `document`. Note that the iframe is hidden from view. + * + * @param name Name of the iframe. + * @returns {HTMLIFrameElement} The created iframe + */ + function initIframeForUpload(name) { + var iframe = qq.toElement("
    "); + jQuery("#TB_overlay").click(tb_remove); + } + } + else + {// all others + if (document.getElementById("TB_overlay") === null) + { + jQuery("body") + .append("
    "); + jQuery("#TB_overlay").click(tb_remove); + } + } + + if (caption === null) + { + caption = ""; + } + jQuery("body").append( + "
    ");// add + // loader + // to + // the + // page + jQuery('#TB_load').show();// show loader + + var baseURL; + if (url.indexOf("?") !== -1) + { // ff there is a query string involved + baseURL = url.substr(0, url.indexOf("?")); + } + else + { + baseURL = url; + } + + var urlString = /\.jpg|\.jpeg|\.png|\.gif|\.bmp/g; + var urlType = baseURL.toLowerCase().match(urlString); + + if (true) + { // (urlType == '.jpg' || urlType == '.jpeg' || urlType == '.png' || + // urlType == '.gif' || urlType == '.bmp'){//code to show images + + TB_PrevCaption = ""; + TB_PrevURL = ""; + TB_PrevHTML = ""; + TB_NextCaption = ""; + TB_NextURL = ""; + TB_NextHTML = ""; + TB_imageCount = ""; + TB_FoundURL = false; + if (imageGroup) + { + TB_TempArray = jQuery("a[rel=" + imageGroup + "]").get(); + + // edit JoomGallery team + // check multiple links for correction of the counter + // return an array with unique object keys + var uniquearr = new Array(); + uniquearr = joomcheckmulti(TB_TempArray); + var uniquecount = joomuniquelength(uniquearr); + var uniquemaxid = joomidmax(uniquearr, TB_TempArray.length); + + for (TB_Counter = 0; ((TB_Counter < TB_TempArray.length) && (TB_NextHTML === "")); TB_Counter++) + { + if ((TB_TempArray[TB_Counter].href == url)) + { + // actual picture found + var prevImage = TB_Counter - 1; + var nextImage = TB_Counter + 1; + var changed = false; + while (uniquearr[TB_Counter] != true) + { + TB_Counter++; + changed = true; + } + if (changed) + { + prevImage = TB_Counter - 1; + nextImage = TB_Counter + 1; + } + // look for previous and next image + while (uniquearr[prevImage] != true && prevImage >= 0) + { + prevImage--; + } + while (uniquearr[nextImage] != true && nextImage <= uniquemaxid) + { + nextImage++; + } + if (nextImage > uniquemaxid) + { + nextImage = -1; + } + // get the right counter of actual image + var imageactcounter = 0; + if (prevImage < 0) + { + imageactcounter = 1; + } + else + { + imageactcounter = joomgetactcount(uniquearr, TB_TempArray.length, + TB_Counter); + } + // actual image + TB_imageCount = joomgallery_image + " " + (imageactcounter) + " " + + joomgallery_of + " " + (uniquecount); + + // next image if existent + if (nextImage != -1) + { + TB_NextCaption = TB_TempArray[nextImage].title; + TB_NextURL = TB_TempArray[nextImage].href; + // Edit b2m language + TB_NextHTML = "  " + + joomgallery_next + " >"; + } + // previous picture if existent + if (prevImage >= 0) + { + TB_PrevCaption = TB_TempArray[prevImage].title; + TB_PrevURL = TB_TempArray[prevImage].href; + // Edit b2m language + TB_PrevHTML = "  <" + + joomgallery_prev + ""; + } + break; + } + } + } + + imgPreloader = new Image(); + imgPreloader.onload = function() + { + imgPreloader.onload = null; + + // Resizing large images - orginal by Christian Montoya edited by me. + var pagesize = tb_getPageSize(); + var x = pagesize[0] - 150; + var y = pagesize[1] - 150; + var imageWidth = imgPreloader.width; + var imageHeight = imgPreloader.height; + // Edit b2m edit resize + if (resizeJsImage == 1) + { + if (imageWidth > x) + { + imageHeight = imageHeight * (x / imageWidth); + imageWidth = x; + } + if (imageHeight > y) + { + imageWidth = imageWidth * (y / imageHeight); + imageHeight = y; + } + } + // End b2m Edit resize + // End Resizing + + TB_WIDTH = imageWidth + 30; + TB_HEIGHT = imageHeight + 60; + // Edit b2m language + jQuery("#TB_window") + .append( + "" + + "
    " + + caption + + "
    " + + TB_imageCount + + TB_PrevHTML + + TB_NextHTML + + "
    " + joomgallery_close + " " + + joomgallery_press_esc + "
    "); + // End edit b2m language + + jQuery("#TB_closeWindowButton").click(tb_remove); + + if (!(TB_PrevHTML === "")) + { + function goPrev() + { + if (jQuery(document).unbind("click", goPrev)) + { + jQuery(document).unbind("click", goPrev); + } + jQuery("#TB_window").remove(); + jQuery("body").append("
    "); + tb_show(TB_PrevCaption, TB_PrevURL, imageGroup); + return false; + } + jQuery("#TB_prev").click(goPrev); + } + + if (!(TB_NextHTML === "")) + { + function goNext() + { + jQuery("#TB_window").remove(); + jQuery("body").append("
    "); + tb_show(TB_NextCaption, TB_NextURL, imageGroup); + return false; + } + jQuery("#TB_next").click(goNext); + + } + + document.onkeydown = function(e) + { + if (e == null) + { // ie + keycode = event.keyCode; + } + else + { // mozilla + keycode = e.which; + } + + keychar = String.fromCharCode(keycode).toLowerCase(); + + if (keycode == 27) + { // close + tb_remove(); + } + else if (keychar == 'n' || keycode == 39) + { // display next image + if (!(TB_NextHTML == "")) + { + document.onkeydown = ""; + goNext(); + } + } + else if (keychar == 'p' || keycode == 37) + { // display previous image + if (!(TB_PrevHTML == "")) + { + document.onkeydown = ""; + goPrev(); + } + } + }; + + tb_position(); + jQuery("#TB_load").remove(); + jQuery("#TB_ImageOff").click(tb_remove); + jQuery("#TB_window").css( + { + display : "block" + }); // for safari using css instead of show + }; + + imgPreloader.src = url; + } + else + {// code to show html pages + + var queryString = url.replace(/^[^\?]+\??/, ''); + var params = tb_parseQuery(queryString); + + TB_WIDTH = (params['width'] * 1) + 30 || 630; // defaults to 630 if no + // paramaters were added to + // URL + TB_HEIGHT = (params['height'] * 1) + 40 || 440; // defaults to 440 if no + // paramaters were added + // to URL + ajaxContentW = TB_WIDTH - 30; + ajaxContentH = TB_HEIGHT - 45; + + if (url.indexOf('TB_iframe') != -1) + { + urlNoQuery = url.split('TB_'); + // Edit b2m language + jQuery("#TB_window") + .append( + "
    " + + caption + + "
    " + + joomgallery_close + + " " + + joomgallery_press_esc + + "
    "); + } + else + { + if (jQuery("#TB_window").css("display") != "block") + { + if (params['modal'] != "true") + { + jQuery("#TB_window") + .append( + "
    " + + caption + + "
    " + + joomgallery_close + " " + joomgallery_press_esc + + "
    "); + // End Edit b2m language + } + else + { + jQuery("#TB_overlay").unbind(); + jQuery("#TB_window").append( + "
    "); + } + } + else + { + jQuery("#TB_ajaxContent")[0].style.width = ajaxContentW + "px"; + jQuery("#TB_ajaxContent")[0].style.height = ajaxContentH + "px"; + jQuery("#TB_ajaxContent")[0].scrollTop = 0; + jQuery("#TB_ajaxWindowTitle").html(caption); + } + } + + jQuery("#TB_closeWindowButton").click(tb_remove); + + if (url.indexOf('TB_inline') != -1) + { + jQuery("#TB_ajaxContent").html(jQuery('#' + params['inlineId']).html()); + tb_position(); + jQuery("#TB_load").remove(); + jQuery("#TB_window").css( + { + display : "block" + }); + } + else if (url.indexOf('TB_iframe') != -1) + { + tb_position(); + if (frames['TB_iframeContent'] === undefined) + {// be nice to safari + jQuery("#TB_load").remove(); + jQuery("#TB_window").css( + { + display : "block" + }); + jQuery(document).keyup(function(e) + { + var key = e.keyCode; + if (key == 27) + { + tb_remove(); + } + }); + } + } + else + { + jQuery("#TB_ajaxContent").load( + url += "&random=" + (new Date().getTime()), function() + {// to do a post change this load method + tb_position(); + jQuery("#TB_load").remove(); + tb_init("#TB_ajaxContent a.thickbox"); + jQuery("#TB_window").css( + { + display : "block" + }); + }); + } + + } + + if (!params['modal']) + { + document.onkeyup = function(e) + { + if (e == null) + { // ie + keycode = event.keyCode; + } + else + { // mozilla + keycode = e.which; + } + if (keycode == 27) + { // close + tb_remove(); + } + }; + } + + } catch (e) + { + // nothing here + } +} + +// helper functions below +function tb_showIframe() +{ + jQuery("#TB_load").remove(); + jQuery("#TB_window").css( + { + display : "block" + }); +} + +function tb_remove() +{ + jQuery("#TB_imageOff").unbind("click"); + jQuery("#TB_overlay").unbind("click"); + jQuery("#TB_closeWindowButton").unbind("click"); + jQuery("#TB_window").fadeOut("fast", function() + { + jQuery('#TB_window,#TB_overlay,#TB_HideSelect').remove(); + }); + jQuery("#TB_load").remove(); + if (typeof document.body.style.maxHeight == "undefined") + {// if IE 6 + jQuery("body", "html").css( + { + height : "auto", + width : "auto" + }); + jQuery("html").css("overflow", ""); + } + // restore the onkeydown event from JoomGallery + document.onkeydown = joom_onkeydownsave; + + return false; +} + +function tb_position() +{ + jQuery("#TB_window").css( + { + marginLeft : '-' + parseInt((TB_WIDTH / 2), 10) + 'px', + width : TB_WIDTH + 'px' + }); + if (!(jQuery.browser.msie && typeof XMLHttpRequest == 'function')) + { // take away IE6 + jQuery("#TB_window").css( + { + marginTop : '-' + parseInt((TB_HEIGHT / 2), 10) + 'px' + }); + } +} + +function tb_parseQuery(query) +{ + var Params = + {}; + if (!query) + { + return Params; + }// return empty object + var Pairs = query.split(/[;&]/); + for ( var i = 0; i < Pairs.length; i++) + { + var KeyVal = Pairs[i].split('='); + if (!KeyVal || KeyVal.length != 2) + { + continue; + } + var key = unescape(KeyVal[0]); + var val = unescape(KeyVal[1]); + val = val.replace(/\+/g, ' '); + Params[key] = val; + } + return Params; +} + +function tb_getPageSize() +{ + var de = document.documentElement; + var w = window.innerWidth || self.innerWidth || (de && de.clientWidth) + || document.body.clientWidth; + var h = window.innerHeight || self.innerHeight || (de && de.clientHeight) + || document.body.clientHeight; + arrayPageSize = + [ w, h ]; + return arrayPageSize; +} diff --git a/deployed/joomgallery/media/joomgallery/js/upload.js b/deployed/joomgallery/media/joomgallery/js/upload.js new file mode 100644 index 00000000..3228c436 --- /dev/null +++ b/deployed/joomgallery/media/joomgallery/js/upload.js @@ -0,0 +1,175 @@ +// $HeadURL: https://joomgallery.org/svn/joomgallery/JG-3/JG/trunk/media/joomgallery/js/upload.js $ +// $Id: upload.js 4078 2013-02-12 10:56:43Z erftralle $ +/****************************************************************************************\ +** JoomGallery 3 ** +** By: JoomGallery::ProjectTeam ** +** Copyright (C) 2008 - 2013 JoomGallery::ProjectTeam ** +** Based on: JoomGallery 1.0.0 by JoomGallery::ProjectTeam ** +** Released under GNU GPL Public License ** +** License: http://www.gnu.org/copyleft/gpl.html or have a look ** +** at administrator/components/com_joomgallery/LICENSE.TXT ** +\****************************************************************************************/ + +/** + * Validation for upload fields of single upload in frontend and backend + * + * @return boolean True if form can be submitted, false otherwise + * @since 2.1 + */ +function joomOnSubmit() +{ + var form = document.getElementById('upload-form'); + var no_files_selected = true; + var fullfields = new Array(); + var screenshotfieldname = new Array(); + var screenshotfieldvalue = new Array(); + document.id('arrscreenshot').removeClass('invalid'); + document.id('arrscreenshot').set('aria-invalid', 'false'); + document.id('arrscreenshot-lbl').removeClass('invalid'); + document.id('arrscreenshot-lbl').set('aria-invalid', 'false'); + + // Search for filled fields + var counter = 0; + var number_of_fields = 10; + if(typeof jg_inputcounter != "undefined") + { + number_of_fields = jg_inputcounter; + } + for(i = 0; i < number_of_fields; i++) + { + screenshotfieldname[i] = 'arrscreenshot['+i+']'; + screenshotfieldvalue[i] = document.getElementsByName(screenshotfieldname[i])[0].value; + document.id('arrscreenshot' + i).removeClass('invalid'); + document.id('arrscreenshot' + i).set('aria-invalid', 'false'); + if(screenshotfieldvalue[i] != '') + { + no_files_selected = false; + fullfields[counter] = i; + counter++; + } + } + if(no_files_selected) + { + alert(Joomla.JText._('COM_JOOMGALLERY_COMMON_ALERT_YOU_MUST_SELECT_ONE_IMAGE')); + document.getElementsByName(screenshotfieldname[0])[0].focus(); + document.id('arrscreenshot').addClass('invalid'); + document.id('arrscreenshot').set('aria-invalid', 'true'); + document.id('arrscreenshot-lbl').addClass('invalid'); + document.id('arrscreenshot-lbl').set('aria-invalid', 'true'); + + return false; + } + + // Check file extensions + var extensions_not_ok = false; + var searchextensiontest = new Array(); + var searchextension = new Array(); + + // You have to define this RegExp for each item + searchextension[0] = new RegExp('\.jpg$|\.jpeg$|\.jpe$|\.gif$|\.png$','ig'); + searchextension[1] = new RegExp('\.jpg$|\.jpeg$|\.jpe$|\.gif$|\.png$','ig'); + searchextension[2] = new RegExp('\.jpg$|\.jpeg$|\.jpe$|\.gif$|\.png$','ig'); + searchextension[3] = new RegExp('\.jpg$|\.jpeg$|\.jpe$|\.gif$|\.png$','ig'); + searchextension[4] = new RegExp('\.jpg$|\.jpeg$|\.jpe$|\.gif$|\.png$','ig'); + searchextension[5] = new RegExp('\.jpg$|\.jpeg$|\.jpe$|\.gif$|\.png$','ig'); + searchextension[6] = new RegExp('\.jpg$|\.jpeg$|\.jpe$|\.gif$|\.png$','ig'); + searchextension[7] = new RegExp('\.jpg$|\.jpeg$|\.jpe$|\.gif$|\.png$','ig'); + searchextension[8] = new RegExp('\.jpg$|\.jpeg$|\.jpe$|\.gif$|\.png$','ig'); + searchextension[9] = new RegExp('\.jpg$|\.jpeg$|\.jpe$|\.gif$|\.png$','ig'); + for(i = 0; i < fullfields.length; i++) + { + searchextensiontest = searchextension[i].test(screenshotfieldvalue[fullfields[i]]); + if(!searchextensiontest) + { + extensions_not_ok = true; + document.id('arrscreenshot' + fullfields[i]).addClass('invalid'); + document.id('arrscreenshot' + fullfields[i]).set('aria-invalid', 'true'); + } + } + if(extensions_not_ok) + { + alert(Joomla.JText._('COM_JOOMGALLERY_COMMON_ALERT_WRONG_EXTENSION')); + document.getElementsByName(screenshotfieldname[0])[0].focus(); + document.id('arrscreenshot').addClass('invalid'); + document.id('arrscreenshot').set('aria-invalid', 'true'); + document.id('arrscreenshot-lbl').addClass('invalid'); + document.id('arrscreenshot-lbl').set('aria-invalid', 'true'); + + return false; + } + + // Check for special characters if required + if(!jg_filenamewithjs) + { + var filenames_not_ok = false; + var searchwrongchars = /[^a-zA-Z0-9 _-]/; + var lastbackslash = new Array(); + var endoffilename = new Array(); + var filename = new Array(); + for(i = 0; i < fullfields.length; i++) + { + lastbackslash[i] = screenshotfieldvalue[fullfields[i]].lastIndexOf('\\'); + if(lastbackslash[i] < 1) + { + lastbackslash[i] = screenshotfieldvalue[fullfields[i]].lastIndexOf('/'); + } + endoffilename[i] = screenshotfieldvalue[fullfields[i]].lastIndexOf('\.') - screenshotfieldvalue[fullfields[i]].length; + filename[i] = screenshotfieldvalue[fullfields[i]].slice(lastbackslash[i] + 1,endoffilename[i]); + + if(searchwrongchars.test(filename[i])) + { + filenames_not_ok = true; + document.id('arrscreenshot' + fullfields[i]).addClass('invalid'); + document.id('arrscreenshot' + fullfields[i]).set('aria-invalid', 'true'); + } + } + if(filenames_not_ok) + { + alert(Joomla.JText._('COM_JOOMGALLERY_COMMON_ALERT_WRONG_FILENAME')); + document.getElementsByName(screenshotfieldname[0])[0].focus(); + document.id('arrscreenshot').addClass('invalid'); + document.id('arrscreenshot').set('aria-invalid', 'true'); + document.id('arrscreenshot-lbl').addClass('invalid'); + document.id('arrscreenshot-lbl').set('aria-invalid', 'true'); + + return false; + } + } + + // Check whether images have been selected twice + if(fullfields.length> 1 ) + { + var double_files = false; + var field1 = new Number(); + var field2 = new Number(); + for(i = 0; i < fullfields.length; i++) + { + for(j = fullfields.length - 1; j > i; j--) + { + if(screenshotfieldvalue[fullfields[i]].indexOf(screenshotfieldvalue[fullfields[j]]) == 0) + { + double_files = true; + document.id('arrscreenshot' + fullfields[i]).addClass('invalid'); + document.id('arrscreenshot' + fullfields[i]).set('aria-invalid', 'true'); + document.id('arrscreenshot' + fullfields[j]).addClass('invalid'); + document.id('arrscreenshot' + fullfields[j]).set('aria-invalid', 'true'); + field1 = i + 1; + field2 = j + 1 + alert(Joomla.JText._('COM_JOOMGALLERY_UPLOAD_ALERT_FILENAME_DOUBLE_ONE') + field1 + ' ' + Joomla.JText._('COM_JOOMGALLERY_UPLOAD_ALERT_FILENAME_DOUBLE_TWO') + field2 + '.'); + } + } + } + if(double_files) + { + document.getElementsByName(screenshotfieldname[0])[0].focus(); + document.id('arrscreenshot').addClass('invalid'); + document.id('arrscreenshot').set('aria-invalid', 'true'); + document.id('arrscreenshot-lbl').addClass('invalid'); + document.id('arrscreenshot-lbl').set('aria-invalid', 'true'); + + return false; + } + } + + return true; +} \ No newline at end of file diff --git a/deployed/joomgallery/media/joomgallery/js/userpanel.js b/deployed/joomgallery/media/joomgallery/js/userpanel.js new file mode 100644 index 00000000..dd56b373 --- /dev/null +++ b/deployed/joomgallery/media/joomgallery/js/userpanel.js @@ -0,0 +1,117 @@ +/****************************************************************************************\ +** JoomGallery 3 ** +** By: JoomGallery::ProjectTeam ** +** Copyright (C) 2008 - 2015 JoomGallery::ProjectTeam ** +** Based on: JoomGallery 1.0.0 by JoomGallery::ProjectTeam ** +** Released under GNU GPL Public License ** +** License: http://www.gnu.org/copyleft/gpl.html or have a look ** +** at administrator/components/com_joomgallery/LICENSE.TXT ** +\****************************************************************************************/ + +(function ($) { + $.QuickEditingData = function (options) { + ops = $.extend({ + url: '#', + getContentCallback: function() {} + }, options); + + // Toggle visibility of editing units + $('.jg-show-editing-units a, .jg-cancel').click(function () { + if($(this).hasClass('jg-icon-disabled')) { + return false; + } + + $('.jg-show-editing-units').toggle(); + $('.jg-quick-edit-row, .jg-visible-hidden-toggle, #jg-quick-edit-btn-bar').toggle('slow'); + + var id = $(this).attr('data-id'); + if(id) { + $('#imgtitle_' + id).select(); + $('html, body').animate({ + scrollTop: $('#imgtitle_' + id).closest('tr').prev().offset().top + }, 2000); + } + + return false; + }); + + // Don't submit form on key press of 'enter' when editing units are enabled, but send the Ajax request + $('#userpanelForm').submit(function () { + if($('#jg-quick-edit-btn-bar').is(':visible')) { + if(!$('#jg-quick-edit-btn-bar .jg-save').is(':disabled')) { + $('#jg-quick-edit-btn-bar .jg-save').trigger('click'); + } + + return false; + } + + return true; + }); + + // Send the Ajax request for updating image data + $('#jg-quick-edit-btn-bar .jg-save').click(function () { + var imagesdata = {}; + var submit = true; + $('.jg-quick-edit-row.changed').each(function () { + var id = $(this).attr('data-id'); + imagesdata[id] = { + 'imgtitle': $(this).find('#imgtitle_' + id).val(), + 'imgauthor': $(this).find('#imgauthor_' + id).val(), + 'metadesc': $(this).find('#metadesc_' + id).val(), + 'imgtext': ops.getContentCallback('imgtext_' + id) + }; + if(!imagesdata[id].imgtitle) { + alert(Joomla.JText._('COM_JOOMGALLERY_COMMON_ALERT_IMAGE_MUST_HAVE_TITLE')); + $(this).find('#imgtitle_' + id).focus(); + submit = false; + + return false; + } + }); + + if(!submit) { + return; + } + + $.getJSON(ops.url, {images: imagesdata}) + .done(function (response) { + if (response.success === true) { + Joomla.renderMessages({'success' : [Joomla.JText._('COM_JOOMGALLERY_USERPANEL_DATACHANGED_SUCCESS')]}); + $('.jg-show-editing-units').toggle(); + $('.jg-quick-edit-row, .jg-visible-hidden-toggle, #jg-quick-edit-btn-bar').toggle('slow'); + $('.jg-quick-edit-row.changed').each(function () { + var id = $(this).attr('data-id'); + var image_title = $(this).find("input[name='imgtitle']").val(); + $('#jg-title-row-' + id + ' .jg-image-title').html(image_title); + $(this).removeClass('changed'); + }); + $('#jg-quick-edit-btn-bar .jg-save').attr('disabled', 'disabled'); + } else { + alert(response.message); + } + }) + .fail(function(jqxhr, textStatus, error) { + alert(textStatus + ': ' + error); + }); + + return false; + }); + + // Mark image as edited + $('.jg-quick-edit-row input, .jg-quick-edit-row textarea').keyup(function () { + $(this).closest('.jg-quick-edit-row').addClass('changed'); + $('#jg-quick-edit-btn-bar .jg-save').removeAttr('disabled'); + }); + + // Delay adding the 'image marked' detection event for editor iframes so that they have time to load + setTimeout(function() { + $('.jg-quick-edit-row').each(function () { + var id = $(this).attr('data-id'); + $(this).find('iframe').contents().keyup(function () { + $('.jg-quick-edit-row[data-id=\'' + id + '\']').addClass('changed'); + $('#jg-quick-edit-btn-bar .jg-save').removeAttr('disabled'); + }); + }); + }, 3000); + }; +})(jQuery); \ No newline at end of file diff --git a/deployed/joomgallery/plugins/joomgallery/joomfancybox/index.html b/deployed/joomgallery/plugins/joomgallery/joomfancybox/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/joomgallery/plugins/joomgallery/joomfancybox/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/joomgallery/plugins/joomgallery/joomfancybox/joomfancybox.php b/deployed/joomgallery/plugins/joomgallery/joomfancybox/joomfancybox.php new file mode 100644 index 00000000..98916a21 --- /dev/null +++ b/deployed/joomgallery/plugins/joomgallery/joomfancybox/joomfancybox.php @@ -0,0 +1,151 @@ + + * $doc = JFactory::getDocument(); + * $doc->addStyleSheet(JUri::root().'media/plg_exampleopenimage/css/exampleopenimage.css'); + * $doc->addScript(JUri::root().'media/plg_exampleopenimage/js/exampleopenimage.js'); + * $doc->addScriptDeclaration(" jQuery(document).ready(function(){ExampleOpenImage.init()}"); + * + * + * or if using Mootools or jQuery the respective JHtml method: + * + * JHtml::_('jquery.framework'); + * JHtml::_('behavior.framework'); + * + * + * @return void + * @since 1.0 + */ + protected function init() + { + JHtml::_('jquery.framework', $this->params->get('noconflict', 1)); + + $doc = JFactory::getDocument(); + $doc->addStyleSheet(JUri::root().'media/plg_joomfancybox/jquery.fancybox.css?v=2.1.4'); + + // Optionally add helpers css - thumbs + if($this->params->get('thumbs')) + { + $doc->addStyleSheet(JURI::root().'media/plg_joomfancybox/helpers/jquery.fancybox-thumbs.css?v=2.1.4'); + } + + // Optionally add helpers css - button + if($this->params->get('buttons')) + { + $doc->addStyleSheet(JURI::root().'media/plg_joomfancybox/helpers/jquery.fancybox-buttons.css?v=2.1.4'); + } + + if($this->params->get('script_position', 'head') == 'head') + { + // Optionally add mousewheel plugin + if($this->params->get('mousewheel')) + { + $doc->addScript(JURI::root().'media/plg_joomfancybox/helpers/jquery.mousewheel-3.0.6.pack.js'); + } + + $doc->addScript(JURI::root().'media/plg_joomfancybox/jquery.fancybox.pack.js?v=2.1.4'); + + // Optionally add helpers script - button + if($this->params->get('buttons')) + { + $doc->addScript(JURI::root().'media/plg_joomfancybox/helpers/jquery.fancybox-buttons.js?v=1.0.2'); + } + + // Optionally add helpers script - thumbs + if($this->params->get('thumbs')) + { + $doc->addScript(JURI::root().'media/plg_joomfancybox/helpers/jquery.fancybox-thumbs.js?v=2.1.4'); + } + + /*if($this->params->get('media')) + { + // Optionally add helpers script - media + $doc->addScript(JURI::root().'media/plg_joomfancybox/source/helpers/jquery.fancybox-media.js?v=1.0.0'); + }*/ + + if(!$this->params->get('init_script')) + { + $doc->addScriptDeclaration(" jQuery(document).ready(function(){jQuery('a[data-fancybox=\"fancybox\"]').fancybox();})"); + } + else + { + $doc->addScriptDeclaration($this->params->get('init_script')); + } + } + } + + /** + * This method should set an associative array of attributes for the 'a'-Tag (key/value pairs) which opens the image. + * + * + * $attribs['data-rel'] = 'examplebox'; + * $attribs['data-group'] = $group; + * + * + * The example above will create a link tag like that: + * + * ($attribs is passed by references and should only be filled) + * + * By default the attribute 'href' is filled with the URL to the image which shall be opened. You only have to set that + * attribute if you want to change that (the image URL is passed in the third argument of this method). + * + * NOTE!!!: You are not allowed to set the attributes 'title' and 'class' because these are handled internally by JoomGallery. + * + * @param array $attribs Associative array of HTML attributes which you have to fill + * @param object $image An object holding all the relevant data about the image to open + * @param string $img_url The URL to the image which shall be openend + * @param string $group The name of an image group, most popup boxes are able to group the images with that + * @param string $type 'orig' for original image, 'img' for detail image or 'thumb' for thumbnail + * @return void + * @since 1.0 + */ + protected function getLinkAttributes(&$attribs, $image, $img_url, $group, $type) + { + $attribs['data-fancybox'] = 'fancybox'; + $attribs['data-fancybox-group'] = $group; + $attribs['data-fancybox-type'] = 'image'; + + // You can add more fancyBox options here (in the following form), but you shouldn't change the above ones + // $attribs['data-fancybox-