From 3b09abe57133422e0e5e774936d3adc73e2e67ac Mon Sep 17 00:00:00 2001
From: Nathan
Date: Fri, 18 Sep 2026 20:29:17 -0600
Subject: [PATCH] First commit
---
Piwingo/.env | 3 +
Piwingo/compose.yaml | 35 +
.../piwigo-data/mysql/mariadb_upgrade_info | 1 +
Piwingo/piwigo-data/piwigo/.gitignore | 23 +
Piwingo/piwigo-data/piwigo/COPYING.txt | 18 +
Piwingo/piwigo-data/piwigo/LICENSE.txt | 339 +
Piwingo/piwigo-data/piwigo/README.md | 42 +
Piwingo/piwigo-data/piwigo/SECURITY.md | 36 +
Piwingo/piwigo-data/piwigo/about.php | 48 +
Piwingo/piwigo-data/piwigo/action.php | 236 +
Piwingo/piwigo-data/piwigo/admin.php | 428 +
Piwingo/piwigo-data/piwigo/admin/album.php | 85 +
.../piwigo/admin/album_notification.php | 331 +
Piwingo/piwigo-data/piwigo/admin/albums.php | 356 +
.../piwigo/admin/batch_manager.php | 813 +
.../piwigo/admin/batch_manager_global.php | 621 +
.../piwigo/admin/batch_manager_unit.php | 424 +
Piwingo/piwigo-data/piwigo/admin/cat_list.php | 355 +
.../piwigo-data/piwigo/admin/cat_modify.php | 394 +
.../piwigo-data/piwigo/admin/cat_options.php | 253 +
Piwingo/piwigo-data/piwigo/admin/cat_perm.php | 303 +
Piwingo/piwigo-data/piwigo/admin/comments.php | 56 +
.../piwigo/admin/configuration.php | 707 +
.../piwigo/admin/element_set_ranks.php | 234 +
.../piwigo/admin/extend_for_templates.php | 189 +
.../piwigo-data/piwigo/admin/group_list.php | 116 +
.../piwigo-data/piwigo/admin/group_perm.php | 176 +
Piwingo/piwigo-data/piwigo/admin/help.php | 70 +
Piwingo/piwigo-data/piwigo/admin/history.php | 150 +
.../admin/include/add_core_tabs.inc.php | 197 +
.../piwigo/admin/include/albums_tab.inc.php | 30 +
.../include/batch_manager_filters.inc.php | 141 +
.../admin/include/c13y_internal.class.php | 243 +
.../admin/include/check_integrity.class.php | 331 +
.../configuration_sizes_process.inc.php | 267 +
.../configuration_watermark_process.inc.php | 211 +
.../piwigo/admin/include/functions.php | 3903 +++
.../admin/include/functions_history.inc.php | 506 +
.../admin/include/functions_install.inc.php | 113 +
.../admin/include/functions_metadata.php | 437 +
.../functions_notification_by_mail.inc.php | 531 +
.../admin/include/functions_permalinks.php | 189 +
.../admin/include/functions_plugins.inc.php | 31 +
.../admin/include/functions_upgrade.php | 322 +
.../admin/include/functions_upload.inc.php | 1137 +
.../piwigo/admin/include/image.class.php | 926 +
.../piwigo/admin/include/index.php | 15 +
.../piwigo/admin/include/languages.class.php | 431 +
.../piwigo/admin/include/pclzip.lib.php | 5695 +++++
.../include/photos_add_direct_prepare.inc.php | 221 +
.../piwigo/admin/include/plugins.class.php | 843 +
.../piwigo/admin/include/tabsheet.class.php | 144 +
.../piwigo/admin/include/themes.class.php | 770 +
.../piwigo/admin/include/updates.class.php | 668 +
.../piwigo/admin/include/user_tabs.inc.php | 18 +
Piwingo/piwigo-data/piwigo/admin/index.php | 15 +
Piwingo/piwigo-data/piwigo/admin/intro.php | 472 +
.../piwigo-data/piwigo/admin/languages.php | 41 +
.../piwigo/admin/languages_installed.php | 123 +
.../piwigo/admin/languages_new.php | 120 +
.../piwigo-data/piwigo/admin/maintenance.php | 125 +
.../piwigo/admin/maintenance_actions.php | 409 +
.../piwigo/admin/maintenance_env.php | 365 +
.../piwigo/admin/maintenance_sys.php | 382 +
Piwingo/piwigo-data/piwigo/admin/menubar.php | 167 +
.../piwigo/admin/notification_by_mail.php | 739 +
.../piwigo-data/piwigo/admin/permalinks.php | 190 +
Piwingo/piwigo-data/piwigo/admin/photo.php | 82 +
.../piwigo-data/piwigo/admin/photos_add.php | 74 +
.../piwigo/admin/photos_add_applications.php | 25 +
.../piwigo/admin/photos_add_direct.php | 164 +
.../piwigo/admin/photos_add_ftp.php | 33 +
.../piwigo-data/piwigo/admin/picture_coi.php | 98 +
.../piwigo/admin/picture_formats.php | 63 +
.../piwigo/admin/picture_modify.php | 430 +
Piwingo/piwigo-data/piwigo/admin/plugin.php | 59 +
Piwingo/piwigo-data/piwigo/admin/plugins.php | 36 +
.../piwigo/admin/plugins_installed.php | 219 +
.../piwigo-data/piwigo/admin/plugins_new.php | 208 +
.../piwigo-data/piwigo/admin/popuphelp.php | 94 +
Piwingo/piwigo-data/piwigo/admin/profile.php | 34 +
Piwingo/piwigo-data/piwigo/admin/rating.php | 258 +
.../piwigo-data/piwigo/admin/rating_user.php | 253 +
.../piwigo-data/piwigo/admin/site_manager.php | 185 +
.../piwigo/admin/site_reader_local.php | 197 +
.../piwigo-data/piwigo/admin/site_update.php | 1073 +
Piwingo/piwigo-data/piwigo/admin/stats.php | 399 +
Piwingo/piwigo-data/piwigo/admin/tags.php | 165 +
Piwingo/piwigo-data/piwigo/admin/theme.php | 38 +
Piwingo/piwigo-data/piwigo/admin/themes.php | 36 +
.../themes/clear/css/components/general.css | 0
.../admin/themes/clear/icon/cat_move.png | Bin 0 -> 249 bytes
.../themes/clear/icon/category_children.png | Bin 0 -> 1554 bytes
.../themes/clear/icon/category_delete.png | Bin 0 -> 1752 bytes
.../admin/themes/clear/icon/category_edit.png | Bin 0 -> 1606 bytes
.../themes/clear/icon/category_elements.png | Bin 0 -> 1241 bytes
.../themes/clear/icon/category_jump-to.png | Bin 0 -> 1604 bytes
.../clear/icon/category_permissions.png | Bin 0 -> 1839 bytes
.../icon/category_representant_random.png | Bin 0 -> 3171 bytes
.../piwigo/admin/themes/clear/icon/check.png | Bin 0 -> 367 bytes
.../piwigo/admin/themes/clear/icon/delete.png | Bin 0 -> 965 bytes
.../piwigo/admin/themes/clear/icon/edit_s.png | Bin 0 -> 585 bytes
.../piwigo/admin/themes/clear/icon/exit.png | Bin 0 -> 1432 bytes
.../piwigo/admin/themes/clear/icon/help.png | Bin 0 -> 1684 bytes
.../piwigo/admin/themes/clear/icon/home.png | Bin 0 -> 443 bytes
.../piwigo/admin/themes/clear/icon/index.php | 15 +
.../piwigo/admin/themes/clear/icon/infos.png | Bin 0 -> 2250 bytes
.../piwigo/admin/themes/clear/icon/minus.gif | Bin 0 -> 87 bytes
.../piwigo/admin/themes/clear/icon/next.png | Bin 0 -> 348 bytes
.../admin/themes/clear/icon/page_end.png | Bin 0 -> 536 bytes
.../admin/themes/clear/icon/page_top.png | Bin 0 -> 555 bytes
.../admin/themes/clear/icon/permissions.png | Bin 0 -> 749 bytes
.../piwigo/admin/themes/clear/icon/plus.gif | Bin 0 -> 89 bytes
.../admin/themes/clear/icon/preferences.png | Bin 0 -> 714 bytes
.../piwigo/admin/themes/clear/icon/prev.png | Bin 0 -> 349 bytes
.../admin/themes/clear/icon/remove_filter.png | Bin 0 -> 202 bytes
.../themes/clear/icon/remove_filter_hover.png | Bin 0 -> 173 bytes
.../clear/icon/toggle_is_default_group.png | Bin 0 -> 624 bytes
.../admin/themes/clear/icon/uncheck.png | Bin 0 -> 213 bytes
.../admin/themes/clear/icon/validate_s.png | Bin 0 -> 315 bytes
.../admin/themes/clear/icon/virt_category.png | Bin 0 -> 796 bytes
.../admin/themes/clear/icon/warning.png | Bin 0 -> 680 bytes
.../admin/themes/clear/images/cancel.svg | 6 +
.../admin/themes/clear/images/cancelhover.svg | 6 +
.../themes/clear/images/external_active.png | Bin 0 -> 571 bytes
.../themes/clear/images/external_inactive.png | Bin 0 -> 578 bytes
.../clear/images/missing_screenshot.png | Bin 0 -> 1684 bytes
.../themes/clear/images/quickLocalSync.png | Bin 0 -> 8084 bytes
.../admin/themes/clear/images/stripe-cat.png | Bin 0 -> 104 bytes
.../admin/themes/clear/images/transparent.gif | Bin 0 -> 43 bytes
.../piwigo/admin/themes/clear/index.php | 15 +
.../piwigo/admin/themes/clear/mail-css.tpl | 19 +
.../piwigo/admin/themes/clear/theme.css | 977 +
.../admin/themes/clear/themeconf.inc.php | 8 +
.../default/css/components/album_selector.css | 291 +
.../themes/default/css/components/general.css | 331 +
.../admin/themes/default/fontello/LICENSE.txt | 75 +
.../admin/themes/default/fontello/README.txt | 75 +
.../admin/themes/default/fontello/config.json | 990 +
.../themes/default/fontello/css/animation.css | 85 +
.../default/fontello/css/fontello-codes.css | 137 +
.../fontello/css/fontello-embedded.css | 195 +
.../fontello/css/fontello-ie7-codes.css | 137 +
.../default/fontello/css/fontello-ie7.css | 148 +
.../themes/default/fontello/css/fontello.css | 192 +
.../admin/themes/default/fontello/demo.html | 692 +
.../themes/default/fontello/font/fontello.eot | Bin 0 -> 44828 bytes
.../themes/default/fontello/font/fontello.svg | 282 +
.../themes/default/fontello/font/fontello.ttf | Bin 0 -> 44660 bytes
.../default/fontello/font/fontello.woff | Bin 0 -> 28032 bytes
.../default/fontello/font/fontello.woff2 | Bin 0 -> 23296 bytes
.../themes/default/fonts/open-sans/README.md | 17 +
.../themes/default/fonts/open-sans/bower.json | 24 +
.../open-sans/fonts/Bold/OpenSans-Bold.eot | Bin 0 -> 110106 bytes
.../open-sans/fonts/Bold/OpenSans-Bold.svg | 958 +
.../open-sans/fonts/Bold/OpenSans-Bold.ttf | Bin 0 -> 224452 bytes
.../open-sans/fonts/Bold/OpenSans-Bold.woff | Bin 0 -> 56676 bytes
.../open-sans/fonts/Bold/OpenSans-Bold.woff2 | Bin 0 -> 43524 bytes
.../fonts/BoldItalic/OpenSans-BoldItalic.eot | Bin 0 -> 128050 bytes
.../fonts/BoldItalic/OpenSans-BoldItalic.svg | 958 +
.../fonts/BoldItalic/OpenSans-BoldItalic.ttf | Bin 0 -> 213168 bytes
.../fonts/BoldItalic/OpenSans-BoldItalic.woff | Bin 0 -> 51544 bytes
.../BoldItalic/OpenSans-BoldItalic.woff2 | Bin 0 -> 39304 bytes
.../open-sans/fonts/DESCRIPTION.en_us.html | 1 +
.../fonts/ExtraBold/OpenSans-ExtraBold.eot | Bin 0 -> 106770 bytes
.../fonts/ExtraBold/OpenSans-ExtraBold.svg | 21059 ++++++++++++++++
.../fonts/ExtraBold/OpenSans-ExtraBold.ttf | Bin 0 -> 222424 bytes
.../fonts/ExtraBold/OpenSans-ExtraBold.woff | Bin 0 -> 56324 bytes
.../fonts/ExtraBold/OpenSans-ExtraBold.woff2 | Bin 0 -> 43076 bytes
.../OpenSans-ExtraBoldItalic.eot | Bin 0 -> 123774 bytes
.../OpenSans-ExtraBoldItalic.svg | 958 +
.../OpenSans-ExtraBoldItalic.ttf | Bin 0 -> 213336 bytes
.../OpenSans-ExtraBoldItalic.woff | Bin 0 -> 52024 bytes
.../OpenSans-ExtraBoldItalic.woff2 | Bin 0 -> 39388 bytes
.../fonts/Italic/OpenSans-Italic.eot | Bin 0 -> 131338 bytes
.../fonts/Italic/OpenSans-Italic.svg | 958 +
.../fonts/Italic/OpenSans-Italic.ttf | Bin 0 -> 212760 bytes
.../fonts/Italic/OpenSans-Italic.woff | Bin 0 -> 51720 bytes
.../fonts/Italic/OpenSans-Italic.woff2 | Bin 0 -> 39640 bytes
.../default/fonts/open-sans/fonts/LICENSE.txt | 202 +
.../open-sans/fonts/Light/OpenSans-Light.eot | Bin 0 -> 107642 bytes
.../open-sans/fonts/Light/OpenSans-Light.svg | 958 +
.../open-sans/fonts/Light/OpenSans-Light.ttf | Bin 0 -> 222236 bytes
.../open-sans/fonts/Light/OpenSans-Light.woff | Bin 0 -> 55744 bytes
.../fonts/Light/OpenSans-Light.woff2 | Bin 0 -> 42872 bytes
.../LightItalic/OpenSans-LightItalic.eot | Bin 0 -> 133006 bytes
.../LightItalic/OpenSans-LightItalic.svg | 958 +
.../LightItalic/OpenSans-LightItalic.ttf | Bin 0 -> 213024 bytes
.../LightItalic/OpenSans-LightItalic.woff | Bin 0 -> 51692 bytes
.../LightItalic/OpenSans-LightItalic.woff2 | Bin 0 -> 39236 bytes
.../default/fonts/open-sans/fonts/METADATA.pb | 103 +
.../fonts/Regular/OpenSans-Regular.eot | Bin 0 -> 106442 bytes
.../fonts/Regular/OpenSans-Regular.svg | 958 +
.../fonts/Regular/OpenSans-Regular.ttf | Bin 0 -> 217276 bytes
.../fonts/Regular/OpenSans-Regular.woff | Bin 0 -> 53992 bytes
.../fonts/Regular/OpenSans-Regular.woff2 | Bin 0 -> 41684 bytes
.../fonts/Semibold/OpenSans-SemiBold2.eot | Bin 0 -> 108414 bytes
.../fonts/Semibold/OpenSans-Semibold.eot | Bin 0 -> 108414 bytes
.../fonts/Semibold/OpenSans-Semibold.svg | 21053 +++++++++++++++
.../fonts/Semibold/OpenSans-Semibold.ttf | Bin 0 -> 221164 bytes
.../fonts/Semibold/OpenSans-Semibold.woff | Bin 0 -> 56364 bytes
.../fonts/Semibold/OpenSans-Semibold.woff2 | Bin 0 -> 43488 bytes
.../OpenSans-SemiboldItalic.eot | Bin 0 -> 130914 bytes
.../OpenSans-SemiboldItalic.svg | 958 +
.../OpenSans-SemiboldItalic.ttf | Bin 0 -> 212732 bytes
.../OpenSans-SemiboldItalic.woff | Bin 0 -> 52332 bytes
.../OpenSans-SemiboldItalic.woff2 | Bin 0 -> 40600 bytes
.../themes/default/fonts/open-sans/index.html | 85 +
.../default/fonts/open-sans/open-sans.css | 1 +
.../fonts/open-sans/open-sans.expanded.css | 90 +
.../default/fonts/open-sans/open-sans.less | 133 +
.../fonts/open-sans/open-sans.prefixed.css | 90 +
.../default/fonts/open-sans/open-sans.scss | 12 +
.../default/fonts/open-sans/sass/_Bold.scss | 8 +
.../fonts/open-sans/sass/_BoldItalic.scss | 8 +
.../fonts/open-sans/sass/_ExtraBold.scss | 8 +
.../open-sans/sass/_ExtraBoldItalic.scss | 8 +
.../default/fonts/open-sans/sass/_Italic.scss | 8 +
.../default/fonts/open-sans/sass/_Light.scss | 8 +
.../fonts/open-sans/sass/_LightItalic.scss | 8 +
.../fonts/open-sans/sass/_Regular.scss | 8 +
.../fonts/open-sans/sass/_Semibold.scss | 8 +
.../fonts/open-sans/sass/_SemiboldItalic.scss | 8 +
.../default/fonts/open-sans/sass/_mixins.scss | 4 +
.../fonts/open-sans/sass/_variables.scss | 2 +
.../fonts/open-sans/sass/open-sans.scss | 12 +
.../admin/themes/default/icon/cat_move.png | Bin 0 -> 581 bytes
.../themes/default/icon/category_children.png | Bin 0 -> 962 bytes
.../themes/default/icon/category_delete.png | Bin 0 -> 960 bytes
.../themes/default/icon/category_edit.png | Bin 0 -> 1312 bytes
.../themes/default/icon/category_elements.png | Bin 0 -> 1044 bytes
.../themes/default/icon/category_jump-to.png | Bin 0 -> 942 bytes
.../default/icon/category_permissions.png | Bin 0 -> 960 bytes
.../icon/category_representant_random.png | Bin 0 -> 1575 bytes
.../admin/themes/default/icon/check.png | Bin 0 -> 510 bytes
.../admin/themes/default/icon/delete.png | Bin 0 -> 425 bytes
.../admin/themes/default/icon/edit_s.png | Bin 0 -> 817 bytes
.../admin/themes/default/icon/errors.png | Bin 0 -> 4654 bytes
.../piwigo/admin/themes/default/icon/exit.png | Bin 0 -> 816 bytes
.../default/icon/fcbkcomplete_close.gif | Bin 0 -> 90 bytes
.../admin/themes/default/icon/help-min.png | Bin 0 -> 1191 bytes
.../piwigo/admin/themes/default/icon/help.png | Bin 0 -> 774 bytes
.../piwigo/admin/themes/default/icon/home.png | Bin 0 -> 726 bytes
.../admin/themes/default/icon/index.php | 15 +
.../admin/themes/default/icon/infos.png | Bin 0 -> 4693 bytes
.../admin/themes/default/icon/minus.gif | Bin 0 -> 87 bytes
.../piwigo/admin/themes/default/icon/note.png | Bin 0 -> 1862 bytes
.../admin/themes/default/icon/page_end.png | Bin 0 -> 777 bytes
.../admin/themes/default/icon/page_top.png | Bin 0 -> 482 bytes
.../admin/themes/default/icon/permissions.png | Bin 0 -> 421 bytes
.../piwigo/admin/themes/default/icon/plus.gif | Bin 0 -> 89 bytes
.../admin/themes/default/icon/preferences.png | Bin 0 -> 768 bytes
.../default/icon/toggle_is_default_group.png | Bin 0 -> 664 bytes
.../admin/themes/default/icon/uncheck.png | Bin 0 -> 303 bytes
.../admin/themes/default/icon/validate_s.png | Bin 0 -> 492 bytes
.../themes/default/icon/virt_category.png | Bin 0 -> 1094 bytes
.../admin/themes/default/icon/warning.png | Bin 0 -> 680 bytes
.../admin/themes/default/icon/warnings.png | Bin 0 -> 2241 bytes
.../themes/default/images/ajax-loader-bar.gif | Bin 0 -> 10819 bytes
.../themes/default/images/ajax-loader.gif | Bin 0 -> 673 bytes
.../admin/themes/default/images/cancel.svg | 6 +
.../themes/default/images/cancelhover.svg | 6 +
.../images/certification/Certification.svg | 24 +
.../certification/CertificationBlue.svg | 24 +
.../certification/CertificationGhost.svg | 44 +
.../certification/CertificationOrange.svg | 24 +
.../certification/CertificationWarning.svg | 23 +
.../admin/themes/default/images/pbar-ani.gif | Bin 0 -> 7970 bytes
.../themes/default/images/piwigo-grey.svg | 14 +
.../themes/default/images/piwigo-orange.svg | 26 +
.../default/images/piwigo_app_banner.jpg | Bin 0 -> 21612 bytes
.../default/images/promote-newsletter.png | Bin 0 -> 188664 bytes
.../piwigo/admin/themes/default/index.php | 15 +
.../themes/default/js/LocalStorageCache.js | 410 +
.../admin/themes/default/js/addAlbum.js | 122 +
.../admin/themes/default/js/album_selector.js | 736 +
.../piwigo/admin/themes/default/js/albums.js | 920 +
.../themes/default/js/batchManagerFilter.js | 141 +
.../themes/default/js/batchManagerGlobal.js | 525 +
.../themes/default/js/batchManagerUnit.js | 511 +
.../admin/themes/default/js/cat_list.js | 494 +
.../admin/themes/default/js/cat_modify.js | 511 +
.../admin/themes/default/js/cat_search.js | 118 +
.../admin/themes/default/js/comments.js | 618 +
.../piwigo/admin/themes/default/js/common.js | 335 +
.../admin/themes/default/js/datepicker.js | 184 +
.../admin/themes/default/js/doubleSlider.js | 62 +
.../admin/themes/default/js/group_list.js | 976 +
.../piwigo/admin/themes/default/js/history.js | 684 +
.../admin/themes/default/js/intro_tooltips.js | 135 +
.../admin/themes/default/js/jquery.geoip.js | 62 +
.../admin/themes/default/js/maintenance.js | 62 +
.../themes/default/js/maintenance_env.js | 31 +
.../themes/default/js/maintenance_sys.js | 116 +
.../themes/default/js/photos_add_direct.js | 573 +
.../themes/default/js/picture_formats.js | 55 +
.../admin/themes/default/js/picture_modify.js | 77 +
.../themes/default/js/plugins_installated.js | 747 +
.../admin/themes/default/js/plugins_new.js | 317 +
.../piwigo/admin/themes/default/js/stats.js | 259 +
.../piwigo/admin/themes/default/js/tags.js | 1086 +
.../admin/themes/default/js/user_activity.js | 723 +
.../admin/themes/default/js/user_list.js | 2473 ++
.../piwigo/admin/themes/default/print.css | 13 +
.../admin/themes/default/template/admin.tpl | 195 +
.../default/template/album_notification.tpl | 142 +
.../admin/themes/default/template/albums.tpl | 652 +
.../default/template/batch_manager_global.tpl | 610 +
.../default/template/batch_manager_unit.tpl | 375 +
.../themes/default/template/cat_list.tpl | 229 +
.../themes/default/template/cat_modify.tpl | 282 +
.../themes/default/template/cat_options.tpl | 8 +
.../themes/default/template/cat_perm.tpl | 200 +
.../default/template/check_integrity.tpl | 109 +
.../themes/default/template/comments.tpl | 212 +
.../template/configuration_comments.tpl | 171 +
.../template/configuration_default.tpl | 60 +
.../template/configuration_display.tpl | 340 +
.../default/template/configuration_main.tpl | 300 +
.../default/template/configuration_search.tpl | 245 +
.../default/template/configuration_sizes.tpl | 242 +
.../template/configuration_watermark.tpl | 150 +
.../themes/default/template/double_select.tpl | 19 +
.../default/template/element_set_ranks.tpl | 123 +
.../default/template/extend_for_templates.tpl | 33 +
.../admin/themes/default/template/footer.tpl | 124 +
.../themes/default/template/group_list.tpl | 268 +
.../themes/default/template/group_perm.tpl | 9 +
.../admin/themes/default/template/header.tpl | 94 +
.../admin/themes/default/template/help.tpl | 13 +
.../admin/themes/default/template/history.tpl | 742 +
.../template/include/add_album.inc.tpl | 30 +
.../template/include/album_selector.inc.tpl | 110 +
.../default/template/include/autosize.inc.tpl | 9 +
.../include/batch_manager_filter.inc.tpl | 289 +
.../default/template/include/colorbox.inc.tpl | 3 +
.../template/include/datepicker.inc.tpl | 22 +
.../default/template/include/install.inc.tpl | 19 +
.../admin/themes/default/template/install.tpl | 312 +
.../admin/themes/default/template/intro.tpl | 280 +
.../default/template/languages_installed.tpl | 63 +
.../themes/default/template/languages_new.tpl | 41 +
.../default/template/maintenance_actions.tpl | 292 +
.../default/template/maintenance_env.tpl | 69 +
.../default/template/maintenance_sys.tpl | 209 +
.../admin/themes/default/template/menubar.tpl | 81 +
.../default/template/navigation_bar.tpl | 34 +
.../default/template/notification_by_mail.tpl | 172 +
.../themes/default/template/permalinks.tpl | 104 +
.../template/photos_add_applications.tpl | 191 +
.../default/template/photos_add_direct.tpl | 271 +
.../default/template/photos_add_ftp.tpl | 5 +
.../themes/default/template/picture_coi.tpl | 71 +
.../default/template/picture_formats.tpl | 35 +
.../default/template/picture_modify.tpl | 278 +
.../default/template/plugins_installed.tpl | 201 +
.../themes/default/template/plugins_new.tpl | 215 +
.../themes/default/template/popuphelp.tpl | 12 +
.../admin/themes/default/template/rating.tpl | 149 +
.../themes/default/template/rating_user.tpl | 242 +
.../themes/default/template/site_manager.tpl | 76 +
.../themes/default/template/site_update.tpl | 143 +
.../admin/themes/default/template/stats.tpl | 58 +
.../themes/default/template/tabsheet.tpl | 11 +
.../admin/themes/default/template/tags.tpl | 263 +
.../default/template/themes_installed.tpl | 156 +
.../themes/default/template/themes_new.tpl | 35 +
.../template/themes_standard_pages.tpl | 195 +
.../themes/default/template/updates_ext.tpl | 237 +
.../themes/default/template/updates_pwg.tpl | 193 +
.../admin/themes/default/template/upgrade.tpl | 228 +
.../themes/default/template/user_activity.tpl | 578 +
.../themes/default/template/user_list.tpl | 3357 +++
.../themes/default/template/user_perm.tpl | 23 +
.../piwigo/admin/themes/default/theme.css | 8604 +++++++
.../admin/themes/default/themeconf.inc.php | 9 +
.../themes/roma/css/components/general.css | 200 +
.../piwigo/admin/themes/roma/icon/home.png | Bin 0 -> 726 bytes
.../piwigo/admin/themes/roma/icon/next.png | Bin 0 -> 328 bytes
.../piwigo/admin/themes/roma/icon/prev.png | Bin 0 -> 328 bytes
.../admin/themes/roma/images/active_tab.png | Bin 0 -> 2696 bytes
.../admin/themes/roma/images/active_tab2.png | Bin 0 -> 658 bytes
.../admin/themes/roma/images/active_tab3.png | Bin 0 -> 106 bytes
.../admin/themes/roma/images/cancel.svg | 6 +
.../admin/themes/roma/images/cancelhover.svg | 6 +
.../certification/CertificationWarningDM.svg | 1 +
.../themes/roma/images/external_active.png | Bin 0 -> 598 bytes
.../themes/roma/images/external_inactive.png | Bin 0 -> 578 bytes
.../admin/themes/roma/images/fillet.png | Bin 0 -> 153 bytes
.../themes/roma/images/header_msgs-bg.gif | Bin 0 -> 44 bytes
.../admin/themes/roma/images/inactive_tab.png | Bin 0 -> 2248 bytes
.../themes/roma/images/inactive_tab2.png | Bin 0 -> 589 bytes
.../themes/roma/images/inactive_tab3.png | Bin 0 -> 109 bytes
.../themes/roma/images/menuBoxBottom_new.png | Bin 0 -> 1310 bytes
.../themes/roma/images/menuBoxTop_new.png | Bin 0 -> 1653 bytes
.../themes/roma/images/menubar-detail.png | Bin 0 -> 226 bytes
.../admin/themes/roma/images/menubar-top.png | Bin 0 -> 1532 bytes
.../themes/roma/images/missing_screenshot.png | Bin 0 -> 2848 bytes
.../roma/images/quickLocalSync_hover.png | Bin 0 -> 34102 bytes
.../roma/images/quickLocalSync_inactiv.png | Bin 0 -> 17397 bytes
.../admin/themes/roma/images/stripe-cat.png | Bin 0 -> 99 bytes
.../admin/themes/roma/images/transparent.gif | Bin 0 -> 43 bytes
.../piwigo/admin/themes/roma/index.php | 15 +
.../piwigo/admin/themes/roma/mail-css.tpl | 18 +
.../piwigo/admin/themes/roma/theme.css | 2505 ++
.../admin/themes/roma/themeconf.inc.php | 7 +
.../piwigo/admin/themes_installed.php | 177 +
.../piwigo-data/piwigo/admin/themes_new.php | 143 +
.../piwigo/admin/themes_standard_pages.php | 177 +
Piwingo/piwigo-data/piwigo/admin/updates.php | 35 +
.../piwigo-data/piwigo/admin/updates_ext.php | 100 +
.../piwigo-data/piwigo/admin/updates_pwg.php | 173 +
.../piwigo/admin/user_activity.php | 248 +
.../piwigo-data/piwigo/admin/user_list.php | 273 +
.../piwigo-data/piwigo/admin/user_perm.php | 176 +
Piwingo/piwigo-data/piwigo/comments.php | 547 +
Piwingo/piwigo-data/piwigo/doc/COPYING | 340 +
Piwingo/piwigo-data/piwigo/doc/README_ca.txt | 61 +
Piwingo/piwigo-data/piwigo/doc/README_en.txt | 62 +
Piwingo/piwigo-data/piwigo/doc/README_fr.txt | 74 +
Piwingo/piwigo-data/piwigo/doc/index.php | 15 +
.../piwigo-data/piwigo/docs/CONTRIBUTING.md | 71 +
Piwingo/piwigo-data/piwigo/docs/HowToFork.png | Bin 0 -> 14072 bytes
.../piwigo/docs/HowToPullRequest.png | Bin 0 -> 23416 bytes
Piwingo/piwigo-data/piwigo/docs/Issue.PNG | Bin 0 -> 9782 bytes
Piwingo/piwigo-data/piwigo/feed.php | 186 +
.../piwigo-data/piwigo/galleries/index.php | 15 +
Piwingo/piwigo-data/piwigo/i.php | 649 +
Piwingo/piwigo-data/piwigo/identification.php | 169 +
.../piwigo/include/Logger.class.php | 476 +
.../piwigo/include/base32.class.php | 85 +
.../piwigo/include/block.class.php | 324 +
.../piwigo/include/cache.class.php | 128 +
.../piwigo/include/calendar_base.class.php | 369 +
.../piwigo/include/calendar_monthly.class.php | 474 +
.../piwigo/include/calendar_weekly.class.php | 121 +
.../piwigo/include/category_cats.inc.php | 387 +
.../piwigo/include/category_default.inc.php | 153 +
.../piwigo-data/piwigo/include/common.inc.php | 370 +
.../piwigo/include/config_default.inc.php | 1088 +
.../piwigo-data/piwigo/include/constants.php | 112 +
.../include/dblayer/functions_mysql.inc.php | 818 +
.../include/dblayer/functions_mysqli.inc.php | 921 +
.../piwigo/include/derivative.inc.php | 535 +
.../piwigo/include/derivative_params.inc.php | 423 +
.../include/derivative_std_params.inc.php | 359 +
.../piwigo/include/emogrifier.class.php | 682 +
.../piwigo/include/feedcreator.class.php | 1737 ++
.../piwigo-data/piwigo/include/filter.inc.php | 131 +
.../piwigo/include/functions.inc.php | 3128 +++
.../piwigo/include/functions_calendar.inc.php | 304 +
.../piwigo/include/functions_category.inc.php | 806 +
.../piwigo/include/functions_comment.inc.php | 524 +
.../piwigo/include/functions_cookie.inc.php | 124 +
.../piwigo/include/functions_filter.inc.php | 37 +
.../piwigo/include/functions_html.inc.php | 673 +
.../piwigo/include/functions_mail.inc.php | 1149 +
.../piwigo/include/functions_metadata.inc.php | 247 +
.../include/functions_notification.inc.php | 613 +
.../piwigo/include/functions_picture.inc.php | 152 +
.../piwigo/include/functions_plugins.inc.php | 447 +
.../piwigo/include/functions_rate.inc.php | 203 +
.../piwigo/include/functions_search.inc.php | 2139 ++
.../piwigo/include/functions_session.inc.php | 259 +
.../piwigo/include/functions_tag.inc.php | 362 +
.../piwigo/include/functions_url.inc.php | 948 +
.../piwigo/include/functions_user.inc.php | 2918 +++
Piwingo/piwigo-data/piwigo/include/index.php | 15 +
.../piwigo/include/inflectors/en.php | 147 +
.../piwigo/include/inflectors/fr.php | 81 +
.../piwigo/include/jshrink.class.php | 613 +
.../piwigo-data/piwigo/include/mdetect.php | 1287 +
.../piwigo/include/menubar.inc.php | 334 +
.../piwigo-data/piwigo/include/minify/LICENSE | 18 +
.../include/minify/data/js/keywords_after.txt | 7 +
.../minify/data/js/keywords_before.txt | 26 +
.../minify/data/js/keywords_reserved.txt | 63 +
.../include/minify/data/js/operators.txt | 46 +
.../minify/data/js/operators_after.txt | 43 +
.../minify/data/js/operators_before.txt | 43 +
.../include/minify/path-converter/LICENSE | 18 +
.../minify/path-converter/src/Converter.php | 204 +
.../path-converter/src/ConverterInterface.php | 24 +
.../minify/path-converter/src/NoConverter.php | 23 +
.../piwigo/include/minify/src/CSS.php | 897 +
.../piwigo/include/minify/src/Exception.php | 20 +
.../minify/src/Exceptions/BasicException.php | 22 +
.../src/Exceptions/FileImportException.php | 20 +
.../minify/src/Exceptions/IOException.php | 20 +
.../src/Exceptions/PatternMatchException.php | 36 +
.../piwigo/include/minify/src/JS.php | 618 +
.../piwigo/include/minify/src/Minify.php | 571 +
.../piwigo/include/no_photo_yet.inc.php | 98 +
.../piwigo/include/page_header.php | 103 +
.../piwigo-data/piwigo/include/page_tail.php | 103 +
.../piwigo/include/passwordhash.class.php | 276 +
.../piwigo/include/php_compat/gzopen.php | 9 +
.../piwigo/include/php_compat/index.php | 15 +
.../include/php_compat/str_starts_with.php | 8 +
.../include/phpmailer/DSNConfigurator.php | 247 +
.../piwigo/include/phpmailer/Exception.php | 40 +
.../piwigo/include/phpmailer/OAuth.php | 139 +
.../include/phpmailer/OAuthTokenProvider.php | 44 +
.../piwigo/include/phpmailer/PHPMailer.php | 5126 ++++
.../piwigo/include/phpmailer/POP3.php | 467 +
.../piwigo/include/phpmailer/SMTP.php | 1466 ++
.../piwigo-data/piwigo/include/phpqrcode.php | 3311 +++
.../piwigo/include/picture_comment.inc.php | 267 +
.../piwigo/include/picture_metadata.inc.php | 92 +
.../piwigo/include/picture_rate.inc.php | 72 +
.../piwigo/include/pwgsession.class.php | 33 +
.../piwigo/include/pwgsession_php7.class.php | 34 +
.../piwigo/include/search_filters.inc.php | 919 +
.../piwigo/include/section_init.inc.php | 708 +
.../piwigo/include/selected_tags.inc.php | 42 +
.../piwigo/include/smarty/CHANGELOG.md | 3764 +++
.../piwigo-data/piwigo/include/smarty/LICENSE | 179 +
.../piwigo/include/smarty/README.md | 28 +
.../piwigo/include/smarty/SECURITY.md | 20 +
.../include/smarty/libs/Smarty.class.php | 42 +
.../include/smarty/src/BlockHandler/Base.php | 19 +
.../BlockHandler/BlockHandlerInterface.php | 10 +
.../src/BlockHandler/BlockPluginWrapper.php | 19 +
.../smarty/src/BlockHandler/TextFormat.php | 110 +
.../include/smarty/src/Cacheresource/Base.php | 156 +
.../smarty/src/Cacheresource/Custom.php | 303 +
.../include/smarty/src/Cacheresource/File.php | 338 +
.../src/Cacheresource/KeyValueStore.php | 541 +
.../include/smarty/src/Compile/Base.php | 233 +
.../smarty/src/Compile/BlockCompiler.php | 228 +
.../smarty/src/Compile/CompilerInterface.php | 26 +
.../Compile/DefaultHandlerBlockCompiler.php | 29 +
.../DefaultHandlerFunctionCallCompiler.php | 47 +
.../src/Compile/FunctionCallCompiler.php | 79 +
.../src/Compile/Modifier/BCPluginWrapper.php | 19 +
.../smarty/src/Compile/Modifier/Base.php | 49 +
.../Compile/Modifier/CatModifierCompiler.php | 25 +
.../CountCharactersModifierCompiler.php | 21 +
.../CountParagraphsModifierCompiler.php | 19 +
.../CountSentencesModifierCompiler.php | 19 +
.../Modifier/CountWordsModifierCompiler.php | 20 +
.../Modifier/DefaultModifierCompiler.php | 26 +
.../Modifier/EmptyModifierCompiler.php | 19 +
.../Modifier/EscapeModifierCompiler.php | 66 +
.../Modifier/FromCharsetModifierCompiler.php | 21 +
.../Modifier/IndentModifierCompiler.php | 24 +
.../Modifier/IsArrayModifierCompiler.php | 19 +
.../Modifier/IssetModifierCompiler.php | 25 +
.../Modifier/JsonEncodeModifierCompiler.php | 14 +
.../Modifier/LowerModifierCompiler.php | 19 +
.../Modifier/ModifierCompilerInterface.php | 17 +
.../Modifier/Nl2brModifierCompiler.php | 17 +
.../Modifier/NoPrintModifierCompiler.php | 18 +
.../Compile/Modifier/RawModifierCompiler.php | 21 +
.../Modifier/RoundModifierCompiler.php | 18 +
.../Modifier/StrRepeatModifierCompiler.php | 17 +
.../Modifier/StringFormatModifierCompiler.php | 18 +
.../Modifier/StripModifierCompiler.php | 24 +
.../Modifier/StripTagsModifierCompiler.php | 22 +
.../Modifier/StrlenModifierCompiler.php | 18 +
.../Modifier/SubstrModifierCompiler.php | 15 +
.../Modifier/ToCharsetModifierCompiler.php | 21 +
.../Modifier/UnescapeModifierCompiler.php | 34 +
.../Modifier/UpperModifierCompiler.php | 18 +
.../Modifier/WordWrapModifierCompiler.php | 27 +
.../smarty/src/Compile/ModifierCompiler.php | 95 +
.../src/Compile/ObjectMethodBlockCompiler.php | 44 +
.../src/Compile/ObjectMethodCallCompiler.php | 76 +
.../src/Compile/PrintExpressionCompiler.php | 96 +
.../src/Compile/SpecialVariableCompiler.php | 134 +
.../include/smarty/src/Compile/Tag/Append.php | 58 +
.../include/smarty/src/Compile/Tag/Assign.php | 95 +
.../src/Compile/Tag/BCPluginWrapper.php | 31 +
.../include/smarty/src/Compile/Tag/Block.php | 92 +
.../smarty/src/Compile/Tag/BlockClose.php | 110 +
.../smarty/src/Compile/Tag/BreakTag.php | 123 +
.../include/smarty/src/Compile/Tag/Call.php | 81 +
.../smarty/src/Compile/Tag/Capture.php | 72 +
.../smarty/src/Compile/Tag/CaptureClose.php | 43 +
.../smarty/src/Compile/Tag/ConfigLoad.php | 77 +
.../smarty/src/Compile/Tag/ContinueTag.php | 27 +
.../include/smarty/src/Compile/Tag/Debug.php | 45 +
.../smarty/src/Compile/Tag/ElseIfTag.php | 86 +
.../smarty/src/Compile/Tag/ElseTag.php | 29 +
.../smarty/src/Compile/Tag/EvalTag.php | 74 +
.../smarty/src/Compile/Tag/ExtendsTag.php | 87 +
.../smarty/src/Compile/Tag/ForClose.php | 51 +
.../smarty/src/Compile/Tag/ForElse.php | 30 +
.../include/smarty/src/Compile/Tag/ForTag.php | 101 +
.../smarty/src/Compile/Tag/ForeachClose.php | 55 +
.../smarty/src/Compile/Tag/ForeachElse.php | 35 +
.../smarty/src/Compile/Tag/ForeachSection.php | 206 +
.../smarty/src/Compile/Tag/ForeachTag.php | 286 +
.../smarty/src/Compile/Tag/FunctionClose.php | 164 +
.../smarty/src/Compile/Tag/FunctionTag.php | 73 +
.../smarty/src/Compile/Tag/IfClose.php | 48 +
.../include/smarty/src/Compile/Tag/IfTag.php | 70 +
.../smarty/src/Compile/Tag/IncludeTag.php | 189 +
.../smarty/src/Compile/Tag/Inheritance.php | 54 +
.../include/smarty/src/Compile/Tag/Ldelim.php | 41 +
.../smarty/src/Compile/Tag/Nocache.php | 36 +
.../smarty/src/Compile/Tag/NocacheClose.php | 37 +
.../include/smarty/src/Compile/Tag/Rdelim.php | 36 +
.../smarty/src/Compile/Tag/Section.php | 399 +
.../smarty/src/Compile/Tag/SectionClose.php | 48 +
.../smarty/src/Compile/Tag/SectionElse.php | 29 +
.../smarty/src/Compile/Tag/Setfilter.php | 40 +
.../smarty/src/Compile/Tag/SetfilterClose.php | 43 +
.../smarty/src/Compile/Tag/WhileClose.php | 45 +
.../smarty/src/Compile/Tag/WhileTag.php | 72 +
.../smarty/src/Compiler/BaseCompiler.php | 23 +
.../include/smarty/src/Compiler/CodeFrame.php | 126 +
.../smarty/src/Compiler/Configfile.php | 173 +
.../include/smarty/src/Compiler/Template.php | 1512 ++
.../include/smarty/src/CompilerException.php | 73 +
.../piwigo/include/smarty/src/Data.php | 521 +
.../piwigo/include/smarty/src/Debug.php | 370 +
.../include/smarty/src/ErrorHandler.php | 97 +
.../piwigo/include/smarty/src/Exception.php | 16 +
.../smarty/src/Extension/BCPluginsAdapter.php | 229 +
.../include/smarty/src/Extension/Base.php | 41 +
.../smarty/src/Extension/CallbackWrapper.php | 35 +
.../smarty/src/Extension/CoreExtension.php | 49 +
.../smarty/src/Extension/DefaultExtension.php | 757 +
.../src/Extension/ExtensionInterface.php | 83 +
.../smarty/src/Filter/FilterInterface.php | 9 +
.../smarty/src/Filter/FilterPluginWrapper.php | 15 +
.../src/Filter/Output/TrimWhitespace.php | 91 +
.../src/FunctionHandler/BCPluginWrapper.php | 21 +
.../smarty/src/FunctionHandler/Base.php | 21 +
.../smarty/src/FunctionHandler/Count.php | 36 +
.../smarty/src/FunctionHandler/Counter.php | 61 +
.../smarty/src/FunctionHandler/Cycle.php | 90 +
.../smarty/src/FunctionHandler/Fetch.php | 203 +
.../FunctionHandlerInterface.php | 10 +
.../smarty/src/FunctionHandler/HtmlBase.php | 107 +
.../src/FunctionHandler/HtmlCheckboxes.php | 189 +
.../smarty/src/FunctionHandler/HtmlImage.php | 149 +
.../src/FunctionHandler/HtmlOptions.php | 223 +
.../smarty/src/FunctionHandler/HtmlRadios.php | 174 +
.../src/FunctionHandler/HtmlSelectDate.php | 381 +
.../src/FunctionHandler/HtmlSelectTime.php | 334 +
.../smarty/src/FunctionHandler/HtmlTable.php | 161 +
.../smarty/src/FunctionHandler/Mailto.php | 141 +
.../smarty/src/FunctionHandler/Math.php | 140 +
.../smarty/src/Lexer/ConfigfileLexer.php | 707 +
.../smarty/src/Lexer/ConfigfileLexer.plex | 321 +
.../smarty/src/Lexer/TemplateLexer.php | 1083 +
.../smarty/src/Lexer/TemplateLexer.plex | 677 +
.../include/smarty/src/ParseTree/Base.php | 45 +
.../include/smarty/src/ParseTree/Code.php | 45 +
.../include/smarty/src/ParseTree/Dq.php | 97 +
.../smarty/src/ParseTree/DqContent.php | 44 +
.../include/smarty/src/ParseTree/Tag.php | 70 +
.../include/smarty/src/ParseTree/Template.php | 172 +
.../include/smarty/src/ParseTree/Text.php | 59 +
.../smarty/src/Parser/ConfigfileParser.php | 972 +
.../smarty/src/Parser/ConfigfileParser.y | 352 +
.../smarty/src/Parser/TemplateParser.php | 3178 +++
.../smarty/src/Parser/TemplateParser.y | 1394 +
.../smarty/src/Resource/BasePlugin.php | 145 +
.../smarty/src/Resource/CustomPlugin.php | 105 +
.../smarty/src/Resource/ExtendsPlugin.php | 116 +
.../smarty/src/Resource/FilePlugin.php | 183 +
.../smarty/src/Resource/RecompiledPlugin.php | 50 +
.../smarty/src/Resource/StreamPlugin.php | 71 +
.../smarty/src/Resource/StringEval.php | 85 +
.../smarty/src/Resource/StringPlugin.php | 94 +
.../include/smarty/src/Runtime/Block.php | 92 +
.../smarty/src/Runtime/CaptureRuntime.php | 163 +
.../Runtime/DefaultPluginHandlerRuntime.php | 73 +
.../smarty/src/Runtime/ForeachRuntime.php | 160 +
.../smarty/src/Runtime/InheritanceRuntime.php | 243 +
.../smarty/src/Runtime/TplFunctionRuntime.php | 144 +
.../piwigo/include/smarty/src/Security.php | 560 +
.../piwigo/include/smarty/src/Smarty.php | 2239 ++
.../piwigo/include/smarty/src/Template.php | 732 +
.../include/smarty/src/Template/Cached.php | 428 +
.../include/smarty/src/Template/Compiled.php | 305 +
.../include/smarty/src/Template/Config.php | 36 +
.../smarty/src/Template/GeneratedPhpFile.php | 159 +
.../include/smarty/src/Template/Source.php | 285 +
.../include/smarty/src/TemplateBase.php | 425 +
.../piwigo/include/smarty/src/TestInstall.php | 211 +
.../include/smarty/src/UndefinedVariable.php | 19 +
.../piwigo/include/smarty/src/Variable.php | 118 +
.../piwigo/include/smarty/src/debug.tpl | 174 +
.../piwigo/include/smarty/src/functions.php | 253 +
.../piwigo/include/template.class.php | 2137 ++
.../piwigo-data/piwigo/include/totp.class.php | 115 +
.../piwigo-data/piwigo/include/user.inc.php | 144 +
.../piwigo/include/ws_core.inc.php | 710 +
.../piwigo/include/ws_functions.inc.php | 243 +
.../piwigo/include/ws_functions/index.php | 15 +
.../include/ws_functions/pwg.categories.php | 1479 ++
.../include/ws_functions/pwg.comments.php | 243 +
.../include/ws_functions/pwg.extensions.php | 363 +
.../include/ws_functions/pwg.groups.php | 468 +
.../include/ws_functions/pwg.images.php | 3044 +++
.../include/ws_functions/pwg.permissions.php | 230 +
.../piwigo/include/ws_functions/pwg.php | 1231 +
.../piwigo/include/ws_functions/pwg.tags.php | 523 +
.../piwigo/include/ws_functions/pwg.users.php | 1098 +
.../piwigo/include/ws_init.inc.php | 69 +
.../piwigo/include/ws_protocols/index.php | 15 +
.../include/ws_protocols/json_encoder.php | 38 +
.../include/ws_protocols/php_encoder.php | 38 +
.../include/ws_protocols/rest_encoder.php | 269 +
.../include/ws_protocols/rest_handler.php | 46 +
.../include/ws_protocols/xmlrpc_encoder.php | 99 +
Piwingo/piwigo-data/piwigo/index.php | 443 +
Piwingo/piwigo-data/piwigo/install.php | 547 +
Piwingo/piwigo-data/piwigo/install/config.sql | 82 +
.../piwigo/install/db/100-database.php | 37 +
.../piwigo/install/db/101-database.php | 50 +
.../piwigo/install/db/102-database.php | 30 +
.../piwigo/install/db/103-database.php | 27 +
.../piwigo/install/db/104-database.php | 71 +
.../piwigo/install/db/105-database.php | 27 +
.../piwigo/install/db/106-database.php | 33 +
.../piwigo/install/db/107-database.php | 27 +
.../piwigo/install/db/108-database.php | 112 +
.../piwigo/install/db/109-database.php | 26 +
.../piwigo/install/db/110-database.php | 102 +
.../piwigo/install/db/111-database.php | 38 +
.../piwigo/install/db/112-database.php | 39 +
.../piwigo/install/db/113-database.php | 26 +
.../piwigo/install/db/114-database.php | 23 +
.../piwigo/install/db/115-database.php | 23 +
.../piwigo/install/db/116-database.php | 33 +
.../piwigo/install/db/117-database.php | 50 +
.../piwigo/install/db/118-database.php | 26 +
.../piwigo/install/db/119-database.php | 33 +
.../piwigo/install/db/120-database.php | 24 +
.../piwigo/install/db/121-database.php | 24 +
.../piwigo/install/db/122-database.php | 68 +
.../piwigo/install/db/123-database.php | 203 +
.../piwigo/install/db/124-database.php | 45 +
.../piwigo/install/db/125-database.php | 182 +
.../piwigo/install/db/126-database.php | 33 +
.../piwigo/install/db/127-database.php | 33 +
.../piwigo/install/db/128-database.php | 23 +
.../piwigo/install/db/129-database.php | 23 +
.../piwigo/install/db/130-database.php | 26 +
.../piwigo/install/db/131-database.php | 20 +
.../piwigo/install/db/132-database.php | 21 +
.../piwigo/install/db/133-database.php | 20 +
.../piwigo/install/db/134-database.php | 28 +
.../piwigo/install/db/135-database.php | 32 +
.../piwigo/install/db/136-database.php | 22 +
.../piwigo/install/db/137-database.php | 47 +
.../piwigo/install/db/138-database.php | 20 +
.../piwigo/install/db/139-database.php | 49 +
.../piwigo/install/db/140-database.php | 22 +
.../piwigo/install/db/141-database.php | 30 +
.../piwigo/install/db/142-database.php | 20 +
.../piwigo/install/db/143-database.php | 45 +
.../piwigo/install/db/144-database.php | 28 +
.../piwigo/install/db/145-database.php | 29 +
.../piwigo/install/db/146-database.php | 24 +
.../piwigo/install/db/147-database.php | 31 +
.../piwigo/install/db/148-database.php | 24 +
.../piwigo/install/db/149-database.php | 25 +
.../piwigo/install/db/150-database.php | 65 +
.../piwigo/install/db/151-database.php | 21 +
.../piwigo/install/db/152-database.php | 25 +
.../piwigo/install/db/153-database.php | 44 +
.../piwigo/install/db/154-database.php | 31 +
.../piwigo/install/db/155-database.php | 21 +
.../piwigo/install/db/156-database.php | 25 +
.../piwigo/install/db/157-database.php | 21 +
.../piwigo/install/db/158-database.php | 33 +
.../piwigo/install/db/159-database.php | 24 +
.../piwigo/install/db/160-database.php | 26 +
.../piwigo/install/db/161-database.php | 53 +
.../piwigo/install/db/162-database.php | 25 +
.../piwigo/install/db/163-database.php | 23 +
.../piwigo/install/db/164-database.php | 23 +
.../piwigo/install/db/165-database.php | 31 +
.../piwigo/install/db/166-database.php | 26 +
.../piwigo/install/db/167-database.php | 21 +
.../piwigo/install/db/168-database.php | 20 +
.../piwigo/install/db/169-database.php | 21 +
.../piwigo/install/db/170-database.php | 22 +
.../piwigo/install/db/171-database.php | 22 +
.../piwigo/install/db/172-database.php | 20 +
.../piwigo/install/db/173-database.php | 20 +
.../piwigo/install/db/174-database.php | 20 +
.../piwigo/install/db/175-database.php | 21 +
.../piwigo/install/db/176-database.php | 36 +
.../piwigo/install/db/177-database.php | 35 +
.../piwigo/install/db/178-database.php | 22 +
.../piwigo/install/db/179-database.php | 24 +
.../piwigo/install/db/180-database.php | 22 +
.../piwigo/install/db/181-database.php | 33 +
.../piwigo/install/db/61-database.php | 35 +
.../piwigo/install/db/62-database.php | 33 +
.../piwigo/install/db/63-database.php | 58 +
.../piwigo/install/db/64-database.php | 35 +
.../piwigo/install/db/65-database.php | 285 +
.../piwigo/install/db/66-database.php | 33 +
.../piwigo/install/db/67-database.php | 33 +
.../piwigo/install/db/68-database.php | 40 +
.../piwigo/install/db/69-database.php | 43 +
.../piwigo/install/db/70-database.php | 38 +
.../piwigo/install/db/71-database.php | 43 +
.../piwigo/install/db/72-database.php | 33 +
.../piwigo/install/db/73-database.php | 31 +
.../piwigo/install/db/74-database.php | 33 +
.../piwigo/install/db/75-database.php | 31 +
.../piwigo/install/db/76-database.php | 31 +
.../piwigo/install/db/77-database.php | 39 +
.../piwigo/install/db/78-database.php | 31 +
.../piwigo/install/db/79-database.php | 32 +
.../piwigo/install/db/80-database.php | 973 +
.../piwigo/install/db/81-database.php | 35 +
.../piwigo/install/db/82-database.php | 29 +
.../piwigo/install/db/83-database.php | 44 +
.../piwigo/install/db/84-database.php | 81 +
.../piwigo/install/db/85-database.php | 36 +
.../piwigo/install/db/86-database.php | 24 +
.../piwigo/install/db/87-database.php | 39 +
.../piwigo/install/db/88-database.php | 34 +
.../piwigo/install/db/89-database.php | 29 +
.../piwigo/install/db/90-database.php | 47 +
.../piwigo/install/db/91-database.php | 39 +
.../piwigo/install/db/92-database.php | 42 +
.../piwigo/install/db/93-database.php | 27 +
.../piwigo/install/db/94-database.php | 94 +
.../piwigo/install/db/95-database.php | 38 +
.../piwigo/install/db/96-database.php | 31 +
.../piwigo/install/db/97-database.php | 48 +
.../piwigo/install/db/98-database.php | 37 +
.../piwigo/install/db/99-database.php | 25 +
.../piwigo-data/piwigo/install/db/index.php | 15 +
.../piwigo-data/piwigo/install/hosting.php | 44 +
Piwingo/piwigo-data/piwigo/install/index.php | 15 +
.../piwigo-data/piwigo/install/obsolete.list | 146 +
.../piwigo/install/obsolete_extensions.list | 13 +
.../install/php5_apache_configuration.php | 186 +
.../piwigo/install/piwigo_structure-mysql.sql | 540 +
.../piwigo/install/upgrade_1.3.0.php | 111 +
.../piwigo/install/upgrade_1.3.1.php | 598 +
.../piwigo/install/upgrade_1.4.0.php | 277 +
.../piwigo/install/upgrade_1.5.0.php | 454 +
.../piwigo/install/upgrade_1.6.0.php | 39 +
.../piwigo/install/upgrade_1.6.2.php | 332 +
.../piwigo/install/upgrade_1.7.0.php | 103 +
.../piwigo/install/upgrade_11.0.0.php | 111 +
.../piwigo/install/upgrade_12.0.0.php | 111 +
.../piwigo/install/upgrade_13.0.0.php | 111 +
.../piwigo/install/upgrade_14.0.0.php | 111 +
.../piwigo/install/upgrade_15.0.0.php | 111 +
.../piwigo/install/upgrade_2.0.0.php | 103 +
.../piwigo/install/upgrade_2.1.0.php | 103 +
.../piwigo/install/upgrade_2.10.0.php | 111 +
.../piwigo/install/upgrade_2.2.0.php | 103 +
.../piwigo/install/upgrade_2.3.0.php | 110 +
.../piwigo/install/upgrade_2.4.0.php | 110 +
.../piwigo/install/upgrade_2.5.0.php | 110 +
.../piwigo/install/upgrade_2.6.0.php | 111 +
.../piwigo/install/upgrade_2.7.0.php | 111 +
.../piwigo/install/upgrade_2.8.0.php | 111 +
.../piwigo/install/upgrade_2.9.0.php | 111 +
.../piwigo/language/af_ZA/about.html | 8 +
.../piwigo/language/af_ZA/admin.lang.php | 973 +
.../piwigo/language/af_ZA/af_ZA.jpg | Bin 0 -> 1158 bytes
.../piwigo/language/af_ZA/common.lang.php | 413 +
.../language/af_ZA/help/cat_modify.html | 110 +
.../piwigo/language/af_ZA/help/cat_move.html | 12 +
.../language/af_ZA/help/permalinks.html | 7 +
.../piwigo/language/af_ZA/help/search.html | 19 +
.../language/af_ZA/help/synchronize.html | 14 +
.../piwigo/language/af_ZA/help/user_list.html | 23 +
.../piwigo/language/af_ZA/index.php | 15 +
.../piwigo/language/af_ZA/install.lang.php | 52 +
.../piwigo-data/piwigo/language/af_ZA/iso.txt | 1 +
.../piwigo/language/af_ZA/upgrade.lang.php | 27 +
.../piwigo/language/ar_EG/ar_EG.jpg | Bin 0 -> 1031 bytes
.../piwigo/language/ar_EG/common.lang.php | 415 +
.../piwigo/language/ar_EG/index.php | 15 +
.../piwigo/language/ar_EG/install.lang.php | 55 +
.../piwigo-data/piwigo/language/ar_EG/iso.txt | 1 +
.../piwigo/language/ar_MA/ar_MA.jpg | Bin 0 -> 684 bytes
.../piwigo/language/ar_MA/common.lang.php | 24 +
.../piwigo/language/ar_MA/index.php | 15 +
.../piwigo-data/piwigo/language/ar_MA/iso.txt | 1 +
.../piwigo/language/ar_SA/Translator.txt | 6 +
.../piwigo/language/ar_SA/about.html | 6 +
.../piwigo/language/ar_SA/admin.lang.php | 977 +
.../piwigo/language/ar_SA/ar_SA.jpg | Bin 0 -> 962 bytes
.../piwigo/language/ar_SA/common.lang.php | 423 +
.../language/ar_SA/help/cat_modify.html | 142 +
.../piwigo/language/ar_SA/help/cat_move.html | 12 +
.../language/ar_SA/help/cat_options.html | 22 +
.../piwigo/language/ar_SA/help/cat_perm.html | 14 +
.../language/ar_SA/help/configuration.html | 141 +
.../ar_SA/help/extend_for_templates.html | 92 +
.../language/ar_SA/help/group_list.html | 22 +
.../language/ar_SA/help/help_add_photos.html | 21 +
.../language/ar_SA/help/help_groups.html | 7 +
.../piwigo/language/ar_SA/help/help_misc.html | 9 +
.../language/ar_SA/help/help_permissions.html | 59 +
.../ar_SA/help/help_virtual_links.html | 9 +
.../piwigo/language/ar_SA/help/history.html | 41 +
.../language/ar_SA/help/maintenance.html | 52 +
.../ar_SA/help/notification_by_mail.html | 16 +
.../language/ar_SA/help/permalinks.html | 9 +
.../language/ar_SA/help/photos_add_ftp.html | 114 +
.../piwigo/language/ar_SA/help/search.html | 21 +
.../language/ar_SA/help/synchronize.html | 7 +
.../piwigo/language/ar_SA/help/user_list.html | 29 +
.../piwigo/language/ar_SA/index.php | 15 +
.../piwigo/language/ar_SA/install.lang.php | 52 +
.../piwigo-data/piwigo/language/ar_SA/iso.txt | 1 +
.../piwigo/language/ar_SA/upgrade.lang.php | 27 +
.../piwigo/language/az_AZ/az_AZ.jpg | Bin 0 -> 1145 bytes
.../piwigo/language/az_AZ/common.lang.php | 68 +
.../piwigo-data/piwigo/language/az_AZ/iso.txt | 1 +
.../piwigo/language/bg_BG/about.html | 6 +
.../piwigo/language/bg_BG/admin.lang.php | 1422 ++
.../piwigo/language/bg_BG/bg_BG.jpg | Bin 0 -> 1118 bytes
.../piwigo/language/bg_BG/common.lang.php | 544 +
.../language/bg_BG/help/cat_modify.html | 124 +
.../piwigo/language/bg_BG/help/cat_move.html | 14 +
.../language/bg_BG/help/cat_options.html | 21 +
.../piwigo/language/bg_BG/help/cat_perm.html | 14 +
.../language/bg_BG/help/group_list.html | 22 +
.../language/bg_BG/help/help_add_photos.html | 30 +
.../language/bg_BG/help/help_groups.html | 11 +
.../piwigo/language/bg_BG/help/help_misc.html | 7 +
.../language/bg_BG/help/permalinks.html | 7 +
.../piwigo/language/bg_BG/help/search.html | 23 +
.../language/bg_BG/help/synchronize.html | 14 +
.../piwigo/language/bg_BG/help/user_list.html | 23 +
.../piwigo/language/bg_BG/index.php | 15 +
.../piwigo/language/bg_BG/install.lang.php | 53 +
.../piwigo-data/piwigo/language/bg_BG/iso.txt | 1 +
.../piwigo/language/bg_BG/upgrade.lang.php | 25 +
.../piwigo/language/bn_IN/bn_IN.jpg | Bin 0 -> 1094 bytes
.../piwigo/language/bn_IN/common.lang.php | 69 +
.../piwigo-data/piwigo/language/bn_IN/iso.txt | 1 +
.../piwigo/language/br_FR/about.html | 5 +
.../piwigo/language/br_FR/admin.lang.php | 1035 +
.../piwigo/language/br_FR/br_FR.jpg | Bin 0 -> 827 bytes
.../piwigo/language/br_FR/common.lang.php | 457 +
.../piwigo/language/br_FR/help/help_misc.html | 9 +
.../piwigo/language/br_FR/install.lang.php | 51 +
.../piwigo-data/piwigo/language/br_FR/iso.txt | 1 +
.../piwigo/language/br_FR/upgrade.lang.php | 25 +
.../piwigo/language/ca_ES/about.html | 12 +
.../piwigo/language/ca_ES/admin.lang.php | 1440 ++
.../piwigo/language/ca_ES/ca_ES.jpg | Bin 0 -> 1432 bytes
.../piwigo/language/ca_ES/common.lang.php | 536 +
.../language/ca_ES/help/cat_modify.html | 123 +
.../piwigo/language/ca_ES/help/cat_move.html | 11 +
.../language/ca_ES/help/cat_options.html | 26 +
.../piwigo/language/ca_ES/help/cat_perm.html | 11 +
.../language/ca_ES/help/configuration.html | 89 +
.../ca_ES/help/extend_for_templates.html | 55 +
.../language/ca_ES/help/group_list.html | 21 +
.../language/ca_ES/help/help_add_photos.html | 22 +
.../language/ca_ES/help/help_groups.html | 7 +
.../piwigo/language/ca_ES/help/help_misc.html | 9 +
.../language/ca_ES/help/help_permissions.html | 57 +
.../ca_ES/help/help_virtual_links.html | 6 +
.../piwigo/language/ca_ES/help/history.html | 32 +
.../language/ca_ES/help/maintenance.html | 50 +
.../ca_ES/help/notification_by_mail.html | 15 +
.../language/ca_ES/help/permalinks.html | 8 +
.../language/ca_ES/help/photos_add_ftp.html | 69 +
.../language/ca_ES/help/quick_search.html | 141 +
.../piwigo/language/ca_ES/help/search.html | 23 +
.../language/ca_ES/help/synchronize.html | 11 +
.../piwigo/language/ca_ES/help/user_list.html | 23 +
.../language/ca_ES/help_quick_search.lang.php | 57 +
.../piwigo/language/ca_ES/install.lang.php | 53 +
.../piwigo-data/piwigo/language/ca_ES/iso.txt | 1 +
.../piwigo/language/ca_ES/upgrade.lang.php | 30 +
.../language/ca_ES/whats_new_15.lang.php | 11 +
.../language/ca_ES/whats_new_16.lang.php | 10 +
.../piwigo/language/cs_CZ/about.html | 7 +
.../piwigo/language/cs_CZ/admin.lang.php | 1432 ++
.../piwigo/language/cs_CZ/common.lang.php | 540 +
.../piwigo/language/cs_CZ/cs_CZ.jpg | Bin 0 -> 1197 bytes
.../language/cs_CZ/help/cat_modify.html | 115 +
.../piwigo/language/cs_CZ/help/cat_move.html | 14 +
.../language/cs_CZ/help/cat_options.html | 27 +
.../piwigo/language/cs_CZ/help/cat_perm.html | 11 +
.../language/cs_CZ/help/configuration.html | 104 +
.../cs_CZ/help/extend_for_templates.html | 88 +
.../language/cs_CZ/help/group_list.html | 22 +
.../language/cs_CZ/help/help_add_photos.html | 22 +
.../language/cs_CZ/help/help_groups.html | 8 +
.../piwigo/language/cs_CZ/help/help_misc.html | 5 +
.../language/cs_CZ/help/help_permissions.html | 54 +
.../cs_CZ/help/help_virtual_links.html | 6 +
.../piwigo/language/cs_CZ/help/history.html | 37 +
.../piwigo/language/cs_CZ/help/index.php | 15 +
.../language/cs_CZ/help/maintenance.html | 26 +
.../cs_CZ/help/notification_by_mail.html | 14 +
.../language/cs_CZ/help/permalinks.html | 7 +
.../language/cs_CZ/help/photos_add_ftp.html | 53 +
.../language/cs_CZ/help/quick_search.html | 141 +
.../piwigo/language/cs_CZ/help/search.html | 19 +
.../language/cs_CZ/help/synchronize.html | 7 +
.../piwigo/language/cs_CZ/help/user_list.html | 25 +
.../language/cs_CZ/help_quick_search.lang.php | 57 +
.../piwigo/language/cs_CZ/index.php | 15 +
.../piwigo/language/cs_CZ/install.lang.php | 53 +
.../piwigo-data/piwigo/language/cs_CZ/iso.txt | 1 +
.../piwigo/language/cs_CZ/upgrade.lang.php | 31 +
.../language/cs_CZ/whats_new_15.lang.php | 11 +
.../language/cs_CZ/whats_new_16.lang.php | 10 +
.../piwigo/language/da_DK/about.html | 5 +
.../piwigo/language/da_DK/admin.lang.php | 1433 ++
.../piwigo/language/da_DK/common.lang.php | 539 +
.../piwigo/language/da_DK/da_DK.jpg | Bin 0 -> 1112 bytes
.../language/da_DK/help/cat_modify.html | 97 +
.../piwigo/language/da_DK/help/cat_move.html | 14 +
.../language/da_DK/help/cat_options.html | 21 +
.../piwigo/language/da_DK/help/cat_perm.html | 11 +
.../language/da_DK/help/configuration.html | 95 +
.../da_DK/help/extend_for_templates.html | 55 +
.../language/da_DK/help/group_list.html | 22 +
.../language/da_DK/help/help_add_photos.html | 21 +
.../language/da_DK/help/help_groups.html | 11 +
.../piwigo/language/da_DK/help/help_misc.html | 9 +
.../language/da_DK/help/help_permissions.html | 54 +
.../da_DK/help/help_virtual_links.html | 8 +
.../piwigo/language/da_DK/help/history.html | 22 +
.../language/da_DK/help/maintenance.html | 26 +
.../da_DK/help/notification_by_mail.html | 14 +
.../language/da_DK/help/permalinks.html | 7 +
.../language/da_DK/help/photos_add_ftp.html | 78 +
.../language/da_DK/help/quick_search.html | 141 +
.../piwigo/language/da_DK/help/search.html | 19 +
.../language/da_DK/help/synchronize.html | 14 +
.../piwigo/language/da_DK/help/user_list.html | 23 +
.../language/da_DK/help_quick_search.lang.php | 57 +
.../piwigo/language/da_DK/index.php | 15 +
.../piwigo/language/da_DK/install.lang.php | 55 +
.../piwigo-data/piwigo/language/da_DK/iso.txt | 1 +
.../piwigo/language/da_DK/upgrade.lang.php | 26 +
.../language/da_DK/whats_new_15.lang.php | 11 +
.../language/da_DK/whats_new_16.lang.php | 10 +
.../piwigo/language/de_DE/about.html | 6 +
.../piwigo/language/de_DE/admin.lang.php | 1434 ++
.../piwigo/language/de_DE/common.lang.php | 537 +
.../piwigo/language/de_DE/de_DE.jpg | Bin 0 -> 1177 bytes
.../language/de_DE/help/cat_modify.html | 159 +
.../piwigo/language/de_DE/help/cat_move.html | 21 +
.../language/de_DE/help/cat_options.html | 24 +
.../piwigo/language/de_DE/help/cat_perm.html | 24 +
.../language/de_DE/help/configuration.html | 216 +
.../de_DE/help/extend_for_templates.html | 109 +
.../language/de_DE/help/group_list.html | 33 +
.../language/de_DE/help/help_add_photos.html | 62 +
.../language/de_DE/help/help_groups.html | 19 +
.../piwigo/language/de_DE/help/help_misc.html | 36 +
.../language/de_DE/help/help_permissions.html | 84 +
.../de_DE/help/help_virtual_links.html | 13 +
.../piwigo/language/de_DE/help/history.html | 38 +
.../piwigo/language/de_DE/help/index.php | 15 +
.../language/de_DE/help/maintenance.html | 74 +
.../de_DE/help/notification_by_mail.html | 19 +
.../language/de_DE/help/permalinks.html | 7 +
.../language/de_DE/help/photos_add_ftp.html | 111 +
.../language/de_DE/help/quick_search.html | 141 +
.../piwigo/language/de_DE/help/search.html | 22 +
.../language/de_DE/help/synchronize.html | 17 +
.../piwigo/language/de_DE/help/user_list.html | 33 +
.../language/de_DE/help_quick_search.lang.php | 57 +
.../piwigo/language/de_DE/index.php | 15 +
.../piwigo/language/de_DE/install.lang.php | 55 +
.../piwigo-data/piwigo/language/de_DE/iso.txt | 1 +
.../piwigo/language/de_DE/upgrade.lang.php | 26 +
.../language/de_DE/whats_new_15.lang.php | 11 +
.../language/de_DE/whats_new_16.lang.php | 10 +
.../piwigo/language/dv_MV/common.lang.php | 122 +
.../piwigo/language/dv_MV/dv_MV.jpg | Bin 0 -> 515 bytes
.../piwigo/language/dv_MV/index.php | 15 +
.../piwigo-data/piwigo/language/dv_MV/iso.txt | 1 +
.../piwigo/language/el_GR/about.html | 8 +
.../piwigo/language/el_GR/admin.lang.php | 1430 ++
.../piwigo/language/el_GR/common.lang.php | 538 +
.../piwigo/language/el_GR/el_GR.jpg | Bin 0 -> 974 bytes
.../language/el_GR/help/cat_modify.html | 132 +
.../piwigo/language/el_GR/help/cat_move.html | 14 +
.../language/el_GR/help/cat_options.html | 22 +
.../piwigo/language/el_GR/help/cat_perm.html | 13 +
.../language/el_GR/help/configuration.html | 99 +
.../el_GR/help/extend_for_templates.html | 52 +
.../language/el_GR/help/group_list.html | 22 +
.../language/el_GR/help/help_add_photos.html | 27 +
.../language/el_GR/help/help_groups.html | 11 +
.../piwigo/language/el_GR/help/help_misc.html | 10 +
.../language/el_GR/help/help_permissions.html | 57 +
.../el_GR/help/help_virtual_links.html | 12 +
.../piwigo/language/el_GR/help/history.html | 22 +
.../language/el_GR/help/maintenance.html | 26 +
.../el_GR/help/notification_by_mail.html | 14 +
.../language/el_GR/help/permalinks.html | 7 +
.../language/el_GR/help/photos_add_ftp.html | 79 +
.../language/el_GR/help/quick_search.html | 141 +
.../piwigo/language/el_GR/help/search.html | 25 +
.../language/el_GR/help/synchronize.html | 14 +
.../piwigo/language/el_GR/help/user_list.html | 23 +
.../language/el_GR/help_quick_search.lang.php | 57 +
.../piwigo/language/el_GR/index.php | 15 +
.../piwigo/language/el_GR/install.lang.php | 53 +
.../piwigo-data/piwigo/language/el_GR/iso.txt | 1 +
.../piwigo/language/el_GR/upgrade.lang.php | 25 +
.../language/el_GR/whats_new_15.lang.php | 11 +
.../language/el_GR/whats_new_16.lang.php | 10 +
.../piwigo/language/en_GB/about.html | 5 +
.../piwigo/language/en_GB/admin.lang.php | 239 +
.../piwigo/language/en_GB/common.lang.php | 327 +
.../piwigo/language/en_GB/en_GB.jpg | Bin 0 -> 1278 bytes
.../language/en_GB/help/quick_search.html | 141 +
.../piwigo/language/en_GB/index.php | 15 +
.../piwigo/language/en_GB/install.lang.php | 51 +
.../piwigo-data/piwigo/language/en_GB/iso.txt | 1 +
.../piwigo/language/en_GB/upgrade.lang.php | 25 +
.../piwigo/language/en_UK/about.html | 7 +
.../piwigo/language/en_UK/admin.lang.php | 1440 ++
.../piwigo/language/en_UK/common.lang.php | 536 +
.../piwigo/language/en_UK/en_UK.jpg | Bin 0 -> 1278 bytes
.../language/en_UK/help/cat_modify.html | 133 +
.../piwigo/language/en_UK/help/cat_move.html | 14 +
.../language/en_UK/help/cat_options.html | 22 +
.../piwigo/language/en_UK/help/cat_perm.html | 13 +
.../language/en_UK/help/configuration.html | 101 +
.../en_UK/help/extend_for_templates.html | 51 +
.../language/en_UK/help/group_list.html | 22 +
.../language/en_UK/help/help_add_photos.html | 29 +
.../language/en_UK/help/help_groups.html | 13 +
.../piwigo/language/en_UK/help/help_misc.html | 9 +
.../language/en_UK/help/help_permissions.html | 16 +
.../en_UK/help/help_virtual_links.html | 12 +
.../piwigo/language/en_UK/help/history.html | 22 +
.../piwigo/language/en_UK/help/index.php | 15 +
.../language/en_UK/help/maintenance.html | 26 +
.../en_UK/help/notification_by_mail.html | 15 +
.../language/en_UK/help/permalinks.html | 7 +
.../language/en_UK/help/photos_add_ftp.html | 81 +
.../language/en_UK/help/quick_search.html | 141 +
.../piwigo/language/en_UK/help/search.html | 24 +
.../language/en_UK/help/synchronize.html | 14 +
.../piwigo/language/en_UK/help/user_list.html | 23 +
.../language/en_UK/help_quick_search.lang.php | 58 +
.../piwigo/language/en_UK/index.php | 15 +
.../piwigo/language/en_UK/install.lang.php | 53 +
.../piwigo-data/piwigo/language/en_UK/iso.txt | 1 +
.../piwigo/language/en_UK/upgrade.lang.php | 29 +
.../language/en_UK/whats_new_15.lang.php | 12 +
.../language/en_UK/whats_new_16.lang.php | 11 +
.../piwigo/language/en_US/admin.lang.php | 9 +
.../piwigo/language/en_US/common.lang.php | 29 +
.../piwigo/language/en_US/en_US.jpg | Bin 0 -> 1068 bytes
.../piwigo/language/en_US/index.php | 15 +
.../piwigo-data/piwigo/language/en_US/iso.txt | 1 +
.../piwigo/language/eo_EO/about.html | 5 +
.../piwigo/language/eo_EO/admin.lang.php | 1012 +
.../piwigo/language/eo_EO/common.lang.php | 417 +
.../piwigo/language/eo_EO/eo_EO.jpg | Bin 0 -> 436 bytes
.../language/eo_EO/help/cat_modify.html | 132 +
.../piwigo/language/eo_EO/help/cat_move.html | 16 +
.../language/eo_EO/help/cat_options.html | 22 +
.../piwigo/language/eo_EO/help/cat_perm.html | 13 +
.../language/eo_EO/help/group_list.html | 22 +
.../language/eo_EO/help/help_groups.html | 11 +
.../piwigo/language/eo_EO/help/help_misc.html | 9 +
.../piwigo/language/eo_EO/help/user_list.html | 23 +
.../piwigo/language/eo_EO/install.lang.php | 52 +
.../piwigo-data/piwigo/language/eo_EO/iso.txt | 1 +
.../piwigo/language/eo_EO/upgrade.lang.php | 25 +
.../piwigo/language/es_AR/about.html | 5 +
.../piwigo/language/es_AR/common.lang.php | 422 +
.../piwigo/language/es_AR/es_AR.jpg | Bin 0 -> 1135 bytes
.../piwigo/language/es_AR/index.php | 15 +
.../piwigo-data/piwigo/language/es_AR/iso.txt | 1 +
.../piwigo/language/es_ES/about.html | 7 +
.../piwigo/language/es_ES/admin.lang.php | 1429 ++
.../piwigo/language/es_ES/common.lang.php | 545 +
.../piwigo/language/es_ES/es_ES.jpg | Bin 0 -> 1173 bytes
.../language/es_ES/help/cat_modify.html | 117 +
.../piwigo/language/es_ES/help/cat_move.html | 12 +
.../language/es_ES/help/cat_options.html | 30 +
.../piwigo/language/es_ES/help/cat_perm.html | 11 +
.../language/es_ES/help/configuration.html | 99 +
.../es_ES/help/extend_for_templates.html | 103 +
.../language/es_ES/help/group_list.html | 21 +
.../language/es_ES/help/help_add_photos.html | 22 +
.../language/es_ES/help/help_groups.html | 3 +
.../piwigo/language/es_ES/help/help_misc.html | 7 +
.../language/es_ES/help/help_permissions.html | 32 +
.../es_ES/help/help_virtual_links.html | 5 +
.../piwigo/language/es_ES/help/history.html | 51 +
.../piwigo/language/es_ES/help/index.php | 15 +
.../language/es_ES/help/maintenance.html | 51 +
.../es_ES/help/notification_by_mail.html | 15 +
.../language/es_ES/help/permalinks.html | 7 +
.../language/es_ES/help/photos_add_ftp.html | 54 +
.../language/es_ES/help/quick_search.html | 141 +
.../piwigo/language/es_ES/help/search.html | 23 +
.../language/es_ES/help/synchronize.html | 11 +
.../piwigo/language/es_ES/help/user_list.html | 23 +
.../language/es_ES/help_quick_search.lang.php | 57 +
.../piwigo/language/es_ES/index.php | 15 +
.../piwigo/language/es_ES/install.lang.php | 54 +
.../piwigo-data/piwigo/language/es_ES/iso.txt | 1 +
.../piwigo/language/es_ES/upgrade.lang.php | 26 +
.../language/es_ES/whats_new_15.lang.php | 11 +
.../language/es_ES/whats_new_16.lang.php | 10 +
.../piwigo/language/es_MX/admin.lang.php | 43 +
.../piwigo/language/es_MX/common.lang.php | 422 +
.../piwigo/language/es_MX/es_MX.jpg | Bin 0 -> 1118 bytes
.../piwigo/language/es_MX/install.lang.php | 52 +
.../piwigo-data/piwigo/language/es_MX/iso.txt | 1 +
.../piwigo/language/es_MX/upgrade.lang.php | 25 +
.../piwigo/language/et_EE/about.html | 5 +
.../piwigo/language/et_EE/admin.lang.php | 1405 ++
.../piwigo/language/et_EE/common.lang.php | 478 +
.../piwigo/language/et_EE/et_EE.jpg | Bin 0 -> 1080 bytes
.../language/et_EE/help/cat_modify.html | 48 +
.../piwigo/language/et_EE/help/cat_move.html | 14 +
.../language/et_EE/help/cat_options.html | 22 +
.../piwigo/language/et_EE/help/cat_perm.html | 14 +
.../language/et_EE/help/configuration.html | 100 +
.../language/et_EE/help/group_list.html | 22 +
.../piwigo/language/et_EE/install.lang.php | 53 +
.../piwigo-data/piwigo/language/et_EE/iso.txt | 1 +
.../piwigo/language/et_EE/upgrade.lang.php | 25 +
.../language/et_EE/whats_new_15.lang.php | 11 +
.../piwigo/language/eu_ES/about.html | 5 +
.../piwigo/language/eu_ES/admin.lang.php | 1400 +
.../piwigo/language/eu_ES/common.lang.php | 464 +
.../piwigo/language/eu_ES/eu_ES.jpg | Bin 0 -> 1088 bytes
.../language/eu_ES/help/cat_modify.html | 107 +
.../piwigo/language/eu_ES/help/cat_move.html | 14 +
.../language/eu_ES/help/cat_options.html | 21 +
.../piwigo/language/eu_ES/help/cat_perm.html | 11 +
.../language/eu_ES/help/configuration.html | 98 +
.../eu_ES/help/extend_for_templates.html | 50 +
.../language/eu_ES/help/group_list.html | 22 +
.../language/eu_ES/help/help_add_photos.html | 21 +
.../language/eu_ES/help/help_groups.html | 7 +
.../piwigo/language/eu_ES/help/help_misc.html | 9 +
.../language/eu_ES/help/help_permissions.html | 54 +
.../eu_ES/help/help_virtual_links.html | 6 +
.../piwigo/language/eu_ES/help/history.html | 22 +
.../language/eu_ES/help/maintenance.html | 26 +
.../eu_ES/help/notification_by_mail.html | 15 +
.../language/eu_ES/help/permalinks.html | 7 +
.../language/eu_ES/help/photos_add_ftp.html | 71 +
.../language/eu_ES/help/quick_search.html | 141 +
.../piwigo/language/eu_ES/help/search.html | 19 +
.../language/eu_ES/help/synchronize.html | 13 +
.../piwigo/language/eu_ES/help/user_list.html | 23 +
.../language/eu_ES/help_quick_search.lang.php | 23 +
.../piwigo/language/eu_ES/install.lang.php | 52 +
.../piwigo-data/piwigo/language/eu_ES/iso.txt | 1 +
.../piwigo/language/eu_ES/upgrade.lang.php | 25 +
.../language/eu_ES/whats_new_15.lang.php | 11 +
.../piwigo/language/fa_IR/about.html | 10 +
.../piwigo/language/fa_IR/admin.lang.php | 1104 +
.../piwigo/language/fa_IR/common.lang.php | 457 +
.../piwigo/language/fa_IR/fa_IR.jpg | Bin 0 -> 774 bytes
.../language/fa_IR/help/cat_modify.html | 133 +
.../piwigo/language/fa_IR/help/cat_move.html | 14 +
.../language/fa_IR/help/cat_options.html | 22 +
.../language/fa_IR/help/help_add_photos.html | 21 +
.../language/fa_IR/help/help_groups.html | 5 +
.../piwigo/language/fa_IR/help/help_misc.html | 9 +
.../piwigo/language/fa_IR/help/index.php | 7 +
.../piwigo/language/fa_IR/help/user_list.html | 23 +
.../language/fa_IR/help_quick_search.lang.php | 27 +
.../piwigo/language/fa_IR/index.php | 15 +
.../piwigo/language/fa_IR/install.lang.php | 56 +
.../piwigo-data/piwigo/language/fa_IR/iso.txt | 1 +
.../piwigo/language/fa_IR/upgrade.lang.php | 28 +
.../language/fa_IR/whats_new_15.lang.php | 11 +
.../piwigo/language/fi_FI/about.html | 7 +
.../piwigo/language/fi_FI/admin.lang.php | 1399 +
.../piwigo/language/fi_FI/common.lang.php | 485 +
.../piwigo/language/fi_FI/fi_FI.jpg | Bin 0 -> 1230 bytes
.../piwigo/language/fi_FI/install.lang.php | 53 +
.../piwigo-data/piwigo/language/fi_FI/iso.txt | 1 +
.../piwigo/language/fi_FI/upgrade.lang.php | 25 +
.../language/fi_FI/whats_new_15.lang.php | 11 +
.../piwigo/language/fr_CA/about.html | 8 +
.../piwigo/language/fr_CA/admin.lang.php | 1028 +
.../piwigo/language/fr_CA/common.lang.php | 425 +
.../piwigo/language/fr_CA/fr_CA.jpg | Bin 0 -> 525 bytes
.../language/fr_CA/help/cat_modify.html | 147 +
.../piwigo/language/fr_CA/help/cat_move.html | 15 +
.../language/fr_CA/help/cat_options.html | 39 +
.../piwigo/language/fr_CA/help/cat_perm.html | 14 +
.../language/fr_CA/help/configuration.html | 138 +
.../fr_CA/help/extend_for_templates.html | 101 +
.../language/fr_CA/help/group_list.html | 21 +
.../language/fr_CA/help/help_add_photos.html | 28 +
.../language/fr_CA/help/help_groups.html | 8 +
.../piwigo/language/fr_CA/help/help_misc.html | 5 +
.../language/fr_CA/help/help_permissions.html | 48 +
.../fr_CA/help/help_virtual_links.html | 5 +
.../piwigo/language/fr_CA/help/history.html | 46 +
.../piwigo/language/fr_CA/help/index.php | 15 +
.../language/fr_CA/help/maintenance.html | 64 +
.../fr_CA/help/notification_by_mail.html | 14 +
.../language/fr_CA/help/permalinks.html | 7 +
.../language/fr_CA/help/photos_add_ftp.html | 89 +
.../language/fr_CA/help/quick_search.html | 141 +
.../piwigo/language/fr_CA/help/search.html | 26 +
.../language/fr_CA/help/synchronize.html | 19 +
.../piwigo/language/fr_CA/help/user_list.html | 27 +
.../language/fr_CA/help_quick_search.lang.php | 9 +
.../piwigo/language/fr_CA/index.php | 15 +
.../piwigo/language/fr_CA/install.lang.php | 52 +
.../piwigo-data/piwigo/language/fr_CA/iso.txt | 1 +
.../piwigo/language/fr_CA/upgrade.lang.php | 30 +
.../piwigo/language/fr_FR/about.html | 8 +
.../piwigo/language/fr_FR/admin.lang.php | 1442 ++
.../piwigo/language/fr_FR/common.lang.php | 536 +
.../piwigo/language/fr_FR/fr_FR.jpg | Bin 0 -> 1083 bytes
.../language/fr_FR/help/cat_modify.html | 141 +
.../piwigo/language/fr_FR/help/cat_move.html | 15 +
.../language/fr_FR/help/cat_options.html | 32 +
.../piwigo/language/fr_FR/help/cat_perm.html | 13 +
.../language/fr_FR/help/configuration.html | 132 +
.../fr_FR/help/extend_for_templates.html | 101 +
.../language/fr_FR/help/group_list.html | 21 +
.../language/fr_FR/help/help_add_photos.html | 32 +
.../language/fr_FR/help/help_groups.html | 9 +
.../piwigo/language/fr_FR/help/help_misc.html | 9 +
.../language/fr_FR/help/help_permissions.html | 19 +
.../fr_FR/help/help_virtual_links.html | 5 +
.../piwigo/language/fr_FR/help/history.html | 44 +
.../piwigo/language/fr_FR/help/index.php | 15 +
.../language/fr_FR/help/maintenance.html | 64 +
.../fr_FR/help/notification_by_mail.html | 14 +
.../language/fr_FR/help/permalinks.html | 7 +
.../language/fr_FR/help/photos_add_ftp.html | 89 +
.../language/fr_FR/help/quick_search.html | 141 +
.../piwigo/language/fr_FR/help/search.html | 25 +
.../language/fr_FR/help/synchronize.html | 19 +
.../piwigo/language/fr_FR/help/user_list.html | 27 +
.../language/fr_FR/help_quick_search.lang.php | 58 +
.../piwigo/language/fr_FR/index.php | 15 +
.../piwigo/language/fr_FR/install.lang.php | 53 +
.../piwigo-data/piwigo/language/fr_FR/iso.txt | 1 +
.../piwigo/language/fr_FR/upgrade.lang.php | 30 +
.../language/fr_FR/whats_new_15.lang.php | 12 +
.../language/fr_FR/whats_new_16.lang.php | 11 +
.../piwigo/language/ga_IE/common.lang.php | 74 +
.../piwigo/language/ga_IE/ga_IE.jpg | Bin 0 -> 1040 bytes
.../piwigo-data/piwigo/language/ga_IE/iso.txt | 1 +
.../piwigo/language/gl_ES/about.html | 8 +
.../piwigo/language/gl_ES/admin.lang.php | 971 +
.../piwigo/language/gl_ES/common.lang.php | 412 +
.../piwigo/language/gl_ES/gl_ES.jpg | Bin 0 -> 277 bytes
.../language/gl_ES/help/cat_modify.html | 124 +
.../piwigo/language/gl_ES/help/cat_move.html | 14 +
.../language/gl_ES/help/cat_options.html | 26 +
.../piwigo/language/gl_ES/help/cat_perm.html | 15 +
.../language/gl_ES/help/configuration.html | 96 +
.../gl_ES/help/extend_for_templates.html | 51 +
.../language/gl_ES/help/group_list.html | 22 +
.../language/gl_ES/help/help_add_photos.html | 26 +
.../language/gl_ES/help/help_groups.html | 10 +
.../piwigo/language/gl_ES/help/help_misc.html | 11 +
.../language/gl_ES/help/help_permissions.html | 59 +
.../gl_ES/help/help_virtual_links.html | 7 +
.../piwigo/language/gl_ES/help/history.html | 24 +
.../language/gl_ES/help/maintenance.html | 26 +
.../gl_ES/help/notification_by_mail.html | 14 +
.../language/gl_ES/help/permalinks.html | 7 +
.../language/gl_ES/help/photos_add_ftp.html | 71 +
.../piwigo/language/gl_ES/help/search.html | 19 +
.../language/gl_ES/help/synchronize.html | 14 +
.../piwigo/language/gl_ES/help/user_list.html | 23 +
.../piwigo/language/gl_ES/install.lang.php | 52 +
.../piwigo-data/piwigo/language/gl_ES/iso.txt | 1 +
.../piwigo/language/gl_ES/upgrade.lang.php | 25 +
.../piwigo/language/gu_IN/common.lang.php | 80 +
.../piwigo/language/gu_IN/gu_IN.jpg | Bin 0 -> 1094 bytes
.../piwigo-data/piwigo/language/gu_IN/iso.txt | 1 +
.../piwigo/language/he_IL/about.html | 5 +
.../piwigo/language/he_IL/admin.lang.php | 1434 ++
.../piwigo/language/he_IL/common.lang.php | 544 +
.../piwigo/language/he_IL/he_IL.jpg | Bin 0 -> 773 bytes
.../piwigo/language/he_IL/help/cat_move.html | 13 +
.../language/he_IL/help/help_add_photos.html | 22 +
.../language/he_IL/help_quick_search.lang.php | 57 +
.../piwigo/language/he_IL/install.lang.php | 53 +
.../piwigo-data/piwigo/language/he_IL/iso.txt | 1 +
.../piwigo/language/he_IL/upgrade.lang.php | 26 +
.../language/he_IL/whats_new_15.lang.php | 11 +
.../language/he_IL/whats_new_16.lang.php | 10 +
.../piwigo/language/hr_HR/about.html | 6 +
.../piwigo/language/hr_HR/admin.lang.php | 778 +
.../piwigo/language/hr_HR/common.lang.php | 405 +
.../language/hr_HR/help/cat_modify.html | 121 +
.../piwigo/language/hr_HR/help/cat_move.html | 14 +
.../language/hr_HR/help/cat_options.html | 31 +
.../piwigo/language/hr_HR/help/cat_perm.html | 14 +
.../language/hr_HR/help/configuration.html | 111 +
.../hr_HR/help/extend_for_templates.html | 100 +
.../language/hr_HR/help/group_list.html | 22 +
.../language/hr_HR/help/help_add_photos.html | 27 +
.../piwigo/language/hr_HR/help/history.html | 45 +
.../piwigo/language/hr_HR/help/index.php | 15 +
.../language/hr_HR/help/maintenance.html | 62 +
.../hr_HR/help/notification_by_mail.html | 15 +
.../language/hr_HR/help/permalinks.html | 7 +
.../piwigo/language/hr_HR/help/search.html | 21 +
.../language/hr_HR/help/synchronize.html | 11 +
.../piwigo/language/hr_HR/help/user_list.html | 33 +
.../piwigo/language/hr_HR/hr_HR.jpg | Bin 0 -> 1253 bytes
.../piwigo/language/hr_HR/index.php | 15 +
.../piwigo/language/hr_HR/install.lang.php | 51 +
.../piwigo-data/piwigo/language/hr_HR/iso.txt | 1 +
.../piwigo/language/hr_HR/upgrade.lang.php | 27 +
.../piwigo/language/hu_HU/README.txt | 6 +
.../piwigo/language/hu_HU/about.html | 8 +
.../piwigo/language/hu_HU/admin.lang.php | 1358 +
.../piwigo/language/hu_HU/common.lang.php | 541 +
.../piwigo/language/hu_HU/help/cat_move.html | 14 +
.../language/hu_HU/help/cat_options.html | 33 +
.../piwigo/language/hu_HU/help/cat_perm.html | 11 +
.../language/hu_HU/help/configuration.html | 108 +
.../language/hu_HU/help/group_list.html | 23 +
.../language/hu_HU/help/help_add_photos.html | 21 +
.../language/hu_HU/help/help_groups.html | 10 +
.../piwigo/language/hu_HU/help/help_misc.html | 6 +
.../language/hu_HU/help/help_permissions.html | 52 +
.../hu_HU/help/help_virtual_links.html | 10 +
.../piwigo/language/hu_HU/help/history.html | 44 +
.../piwigo/language/hu_HU/help/index.php | 15 +
.../language/hu_HU/help/maintenance.html | 12 +
.../hu_HU/help/notification_by_mail.html | 15 +
.../language/hu_HU/help/permalinks.html | 7 +
.../language/hu_HU/help/photos_add_ftp.html | 109 +
.../piwigo/language/hu_HU/help/search.html | 23 +
.../language/hu_HU/help/synchronize.html | 12 +
.../piwigo/language/hu_HU/help/user_list.html | 27 +
.../language/hu_HU/help_quick_search.lang.php | 22 +
.../piwigo/language/hu_HU/hu_HU.jpg | Bin 0 -> 1149 bytes
.../piwigo/language/hu_HU/index.php | 15 +
.../piwigo/language/hu_HU/install.lang.php | 54 +
.../piwigo-data/piwigo/language/hu_HU/iso.txt | 1 +
.../piwigo/language/hu_HU/upgrade.lang.php | 30 +
.../language/hu_HU/whats_new_16.lang.php | 10 +
.../piwigo/language/hy_AM/admin.lang.php | 387 +
.../piwigo/language/hy_AM/common.lang.php | 457 +
.../piwigo/language/hy_AM/hy_AM.jpg | Bin 0 -> 11562 bytes
.../piwigo/language/hy_AM/install.lang.php | 52 +
.../piwigo-data/piwigo/language/hy_AM/iso.txt | 1 +
.../piwigo/language/hy_AM/upgrade.lang.php | 25 +
.../language/hy_AM/whats_new_15.lang.php | 11 +
.../piwigo/language/id_ID/common.lang.php | 415 +
.../piwigo/language/id_ID/id_ID.jpg | Bin 0 -> 998 bytes
.../piwigo/language/id_ID/index.php | 15 +
.../piwigo/language/id_ID/install.lang.php | 34 +
.../piwigo-data/piwigo/language/id_ID/iso.txt | 1 +
Piwingo/piwigo-data/piwigo/language/index.php | 15 +
.../piwigo/language/is_IS/about.html | 8 +
.../piwigo/language/is_IS/admin.lang.php | 1425 ++
.../piwigo/language/is_IS/common.lang.php | 536 +
.../language/is_IS/help_quick_search.lang.php | 57 +
.../piwigo/language/is_IS/index.php | 15 +
.../piwigo/language/is_IS/install.lang.php | 52 +
.../piwigo/language/is_IS/is_IS.jpg | Bin 0 -> 1223 bytes
.../piwigo-data/piwigo/language/is_IS/iso.txt | 1 +
.../piwigo/language/is_IS/upgrade.lang.php | 25 +
.../language/is_IS/whats_new_15.lang.php | 11 +
.../language/is_IS/whats_new_16.lang.php | 10 +
.../piwigo/language/it_IT/about.html | 8 +
.../piwigo/language/it_IT/admin.lang.php | 1432 ++
.../piwigo/language/it_IT/common.lang.php | 536 +
.../language/it_IT/help/cat_modify.html | 141 +
.../piwigo/language/it_IT/help/cat_move.html | 15 +
.../language/it_IT/help/cat_options.html | 32 +
.../piwigo/language/it_IT/help/cat_perm.html | 13 +
.../language/it_IT/help/configuration.html | 132 +
.../it_IT/help/extend_for_templates.html | 101 +
.../language/it_IT/help/group_list.html | 21 +
.../language/it_IT/help/help_add_photos.html | 30 +
.../language/it_IT/help/help_groups.html | 7 +
.../piwigo/language/it_IT/help/help_misc.html | 9 +
.../language/it_IT/help/help_permissions.html | 48 +
.../it_IT/help/help_virtual_links.html | 5 +
.../piwigo/language/it_IT/help/history.html | 44 +
.../piwigo/language/it_IT/help/index.php | 15 +
.../language/it_IT/help/maintenance.html | 64 +
.../it_IT/help/notification_by_mail.html | 14 +
.../language/it_IT/help/permalinks.html | 7 +
.../language/it_IT/help/photos_add_ftp.html | 89 +
.../language/it_IT/help/quick_search.html | 141 +
.../piwigo/language/it_IT/help/search.html | 25 +
.../language/it_IT/help/synchronize.html | 19 +
.../piwigo/language/it_IT/help/user_list.html | 27 +
.../language/it_IT/help_quick_search.lang.php | 57 +
.../piwigo/language/it_IT/index.php | 15 +
.../piwigo/language/it_IT/install.lang.php | 53 +
.../piwigo-data/piwigo/language/it_IT/iso.txt | 1 +
.../piwigo/language/it_IT/it_IT.jpg | Bin 0 -> 1059 bytes
.../piwigo/language/it_IT/upgrade.lang.php | 29 +
.../language/it_IT/whats_new_15.lang.php | 11 +
.../language/it_IT/whats_new_16.lang.php | 10 +
.../piwigo/language/ja_JP/README.txt | 4 +
.../piwigo/language/ja_JP/about.html | 7 +
.../piwigo/language/ja_JP/admin.lang.php | 1308 +
.../piwigo/language/ja_JP/common.lang.php | 432 +
.../language/ja_JP/help/cat_modify.html | 127 +
.../piwigo/language/ja_JP/help/cat_move.html | 14 +
.../language/ja_JP/help/cat_options.html | 31 +
.../piwigo/language/ja_JP/help/cat_perm.html | 14 +
.../language/ja_JP/help/configuration.html | 111 +
.../ja_JP/help/extend_for_templates.html | 85 +
.../language/ja_JP/help/group_list.html | 22 +
.../language/ja_JP/help/help_add_photos.html | 21 +
.../language/ja_JP/help/help_groups.html | 6 +
.../piwigo/language/ja_JP/help/help_misc.html | 6 +
.../language/ja_JP/help/help_permissions.html | 45 +
.../ja_JP/help/help_virtual_links.html | 9 +
.../piwigo/language/ja_JP/help/history.html | 32 +
.../piwigo/language/ja_JP/help/index.php | 15 +
.../language/ja_JP/help/maintenance.html | 56 +
.../ja_JP/help/notification_by_mail.html | 14 +
.../language/ja_JP/help/permalinks.html | 7 +
.../language/ja_JP/help/photos_add_ftp.html | 99 +
.../language/ja_JP/help/quick_search.html | 141 +
.../piwigo/language/ja_JP/help/search.html | 22 +
.../language/ja_JP/help/synchronize.html | 10 +
.../piwigo/language/ja_JP/help/user_list.html | 30 +
.../piwigo/language/ja_JP/index.php | 15 +
.../piwigo/language/ja_JP/install.lang.php | 54 +
.../piwigo-data/piwigo/language/ja_JP/iso.txt | 1 +
.../piwigo/language/ja_JP/ja_JP.jpg | Bin 0 -> 800 bytes
.../piwigo/language/ja_JP/upgrade.lang.php | 29 +
.../piwigo/language/ka_GE/about.html | 6 +
.../piwigo/language/ka_GE/admin.lang.php | 808 +
.../piwigo/language/ka_GE/common.lang.php | 406 +
.../language/ka_GE/help/cat_modify.html | 117 +
.../piwigo/language/ka_GE/help/cat_move.html | 14 +
.../language/ka_GE/help/cat_options.html | 28 +
.../piwigo/language/ka_GE/help/cat_perm.html | 11 +
.../language/ka_GE/help/configuration.html | 103 +
.../ka_GE/help/extend_for_templates.html | 77 +
.../language/ka_GE/help/group_list.html | 22 +
.../language/ka_GE/help/help_add_photos.html | 20 +
.../language/ka_GE/help/help_groups.html | 6 +
.../piwigo/language/ka_GE/help/help_misc.html | 4 +
.../language/ka_GE/help/help_permissions.html | 45 +
.../ka_GE/help/help_virtual_links.html | 8 +
.../piwigo/language/ka_GE/help/history.html | 38 +
.../piwigo/language/ka_GE/help/index.php | 15 +
.../language/ka_GE/help/maintenance.html | 49 +
.../ka_GE/help/notification_by_mail.html | 15 +
.../language/ka_GE/help/permalinks.html | 8 +
.../language/ka_GE/help/photos_add_ftp.html | 110 +
.../piwigo/language/ka_GE/help/search.html | 20 +
.../language/ka_GE/help/synchronize.html | 9 +
.../piwigo/language/ka_GE/help/user_list.html | 29 +
.../piwigo/language/ka_GE/index.php | 15 +
.../piwigo/language/ka_GE/install.lang.php | 51 +
.../piwigo-data/piwigo/language/ka_GE/iso.txt | 1 +
.../piwigo/language/ka_GE/ka_GE.jpg | Bin 0 -> 1908 bytes
.../piwigo/language/ka_GE/upgrade.lang.php | 26 +
.../piwigo/language/km_KH/about.html | 6 +
.../piwigo/language/km_KH/admin.lang.php | 255 +
.../piwigo/language/km_KH/common.lang.php | 446 +
.../piwigo/language/km_KH/index.php | 15 +
.../piwigo/language/km_KH/install.lang.php | 53 +
.../piwigo-data/piwigo/language/km_KH/iso.txt | 1 +
.../piwigo/language/km_KH/km_KH.jpg | Bin 0 -> 503 bytes
.../piwigo/language/km_KH/upgrade.lang.php | 25 +
.../piwigo/language/kn_IN/about.html | 5 +
.../piwigo/language/kn_IN/admin.lang.php | 681 +
.../piwigo/language/kn_IN/common.lang.php | 417 +
.../piwigo/language/kn_IN/install.lang.php | 52 +
.../piwigo-data/piwigo/language/kn_IN/iso.txt | 1 +
.../piwigo/language/kn_IN/kn_IN.jpg | Bin 0 -> 1094 bytes
.../piwigo/language/kn_IN/upgrade.lang.php | 25 +
.../piwigo/language/ko_KR/admin.lang.php | 1424 ++
.../piwigo/language/ko_KR/common.lang.php | 536 +
.../language/ko_KR/help_quick_search.lang.php | 57 +
.../piwigo/language/ko_KR/index.php | 15 +
.../piwigo/language/ko_KR/install.lang.php | 53 +
.../piwigo-data/piwigo/language/ko_KR/iso.txt | 1 +
.../piwigo/language/ko_KR/ko_KR.jpg | Bin 0 -> 1205 bytes
.../piwigo/language/ko_KR/upgrade.lang.php | 25 +
.../language/ko_KR/whats_new_16.lang.php | 10 +
.../piwigo/language/kok_IN/common.lang.php | 113 +
.../piwigo/language/kok_IN/iso.txt | 1 +
.../piwigo/language/kok_IN/kok_IN.jpg | Bin 0 -> 1094 bytes
.../piwigo/language/lb_LU/common.lang.php | 416 +
.../piwigo-data/piwigo/language/lb_LU/iso.txt | 1 +
.../piwigo/language/lb_LU/lb_LU.jpg | Bin 0 -> 1044 bytes
.../piwigo/language/lt_LT/about.html | 6 +
.../piwigo/language/lt_LT/admin.lang.php | 993 +
.../piwigo/language/lt_LT/common.lang.php | 429 +
.../piwigo/language/lt_LT/help/cat_move.html | 14 +
.../language/lt_LT/help/cat_options.html | 22 +
.../lt_LT/help/help_virtual_links.html | 9 +
.../piwigo/language/lt_LT/help/index.php | 7 +
.../piwigo/language/lt_LT/help/search.html | 23 +
.../piwigo/language/lt_LT/help/user_list.html | 22 +
.../piwigo/language/lt_LT/install.lang.php | 52 +
.../piwigo-data/piwigo/language/lt_LT/iso.txt | 1 +
.../piwigo/language/lt_LT/lt_LT.jpg | Bin 0 -> 469 bytes
.../piwigo/language/lt_LT/upgrade.lang.php | 25 +
.../piwigo/language/lv_LV/about.html | 7 +
.../piwigo/language/lv_LV/admin.lang.php | 1134 +
.../piwigo/language/lv_LV/common.lang.php | 420 +
.../language/lv_LV/help/cat_modify.html | 45 +
.../piwigo/language/lv_LV/help/cat_move.html | 14 +
.../language/lv_LV/help/cat_options.html | 16 +
.../piwigo/language/lv_LV/help/cat_perm.html | 11 +
.../language/lv_LV/help/configuration.html | 108 +
.../lv_LV/help/extend_for_templates.html | 85 +
.../language/lv_LV/help/group_list.html | 22 +
.../language/lv_LV/help/help_add_photos.html | 21 +
.../language/lv_LV/help/help_groups.html | 5 +
.../piwigo/language/lv_LV/help/help_misc.html | 9 +
.../language/lv_LV/help/help_permissions.html | 56 +
.../lv_LV/help/help_virtual_links.html | 5 +
.../piwigo/language/lv_LV/help/history.html | 32 +
.../language/lv_LV/help/maintenance.html | 45 +
.../lv_LV/help/notification_by_mail.html | 14 +
.../language/lv_LV/help/permalinks.html | 7 +
.../language/lv_LV/help/photos_add_ftp.html | 96 +
.../language/lv_LV/help/quick_search.html | 141 +
.../piwigo/language/lv_LV/help/search.html | 19 +
.../language/lv_LV/help/synchronize.html | 7 +
.../piwigo/language/lv_LV/help/user_list.html | 31 +
.../piwigo/language/lv_LV/index.php | 15 +
.../piwigo/language/lv_LV/install.lang.php | 53 +
.../piwigo-data/piwigo/language/lv_LV/iso.txt | 1 +
.../piwigo/language/lv_LV/lv_LV.jpg | Bin 0 -> 344 bytes
.../piwigo/language/lv_LV/upgrade.lang.php | 28 +
.../piwigo/language/mk_MK/admin.lang.php | 15 +
.../piwigo/language/mk_MK/common.lang.php | 380 +
.../piwigo/language/mk_MK/index.php | 15 +
.../piwigo/language/mk_MK/install.lang.php | 20 +
.../piwigo-data/piwigo/language/mk_MK/iso.txt | 1 +
.../piwigo/language/mk_MK/mk_MK.jpg | Bin 0 -> 566 bytes
.../piwigo/language/mn_MN/about.html | 8 +
.../piwigo/language/mn_MN/admin.lang.php | 734 +
.../piwigo/language/mn_MN/common.lang.php | 420 +
.../piwigo/language/mn_MN/install.lang.php | 54 +
.../piwigo-data/piwigo/language/mn_MN/iso.txt | 1 +
.../piwigo/language/mn_MN/mn_MN.jpg | Bin 0 -> 481 bytes
.../piwigo/language/mn_MN/upgrade.lang.php | 25 +
.../piwigo/language/ms_MY/common.lang.php | 148 +
.../piwigo-data/piwigo/language/ms_MY/iso.txt | 1 +
.../piwigo/language/ms_MY/ms_MY.jpg | Bin 0 -> 1089 bytes
.../piwigo/language/nb_NO/about.html | 8 +
.../piwigo/language/nb_NO/admin.lang.php | 1428 ++
.../piwigo/language/nb_NO/common.lang.php | 535 +
.../language/nb_NO/help/cat_modify.html | 134 +
.../piwigo/language/nb_NO/help/cat_move.html | 14 +
.../language/nb_NO/help/cat_options.html | 22 +
.../piwigo/language/nb_NO/help/cat_perm.html | 11 +
.../language/nb_NO/help/configuration.html | 117 +
.../nb_NO/help/extend_for_templates.html | 92 +
.../language/nb_NO/help/group_list.html | 22 +
.../language/nb_NO/help/help_add_photos.html | 24 +
.../language/nb_NO/help/help_groups.html | 8 +
.../piwigo/language/nb_NO/help/help_misc.html | 9 +
.../language/nb_NO/help/help_permissions.html | 57 +
.../nb_NO/help/help_virtual_links.html | 5 +
.../piwigo/language/nb_NO/help/history.html | 37 +
.../language/nb_NO/help/maintenance.html | 63 +
.../nb_NO/help/notification_by_mail.html | 14 +
.../language/nb_NO/help/permalinks.html | 7 +
.../language/nb_NO/help/photos_add_ftp.html | 107 +
.../language/nb_NO/help/quick_search.html | 141 +
.../piwigo/language/nb_NO/help/search.html | 19 +
.../language/nb_NO/help/synchronize.html | 12 +
.../piwigo/language/nb_NO/help/user_list.html | 25 +
.../language/nb_NO/help_quick_search.lang.php | 57 +
.../piwigo/language/nb_NO/index.php | 15 +
.../piwigo/language/nb_NO/install.lang.php | 53 +
.../piwigo-data/piwigo/language/nb_NO/iso.txt | 1 +
.../piwigo/language/nb_NO/nb_NO.jpg | Bin 0 -> 1276 bytes
.../piwigo/language/nb_NO/upgrade.lang.php | 26 +
.../language/nb_NO/whats_new_15.lang.php | 11 +
.../language/nb_NO/whats_new_16.lang.php | 10 +
.../piwigo/language/nl_NL/about.html | 9 +
.../piwigo/language/nl_NL/admin.lang.php | 1434 ++
.../piwigo/language/nl_NL/common.lang.php | 556 +
.../language/nl_NL/help/cat_modify.html | 125 +
.../piwigo/language/nl_NL/help/cat_move.html | 15 +
.../language/nl_NL/help/cat_options.html | 30 +
.../piwigo/language/nl_NL/help/cat_perm.html | 12 +
.../language/nl_NL/help/configuration.html | 106 +
.../nl_NL/help/extend_for_templates.html | 87 +
.../language/nl_NL/help/group_list.html | 22 +
.../language/nl_NL/help/help_add_photos.html | 23 +
.../language/nl_NL/help/help_groups.html | 6 +
.../piwigo/language/nl_NL/help/help_misc.html | 11 +
.../language/nl_NL/help/help_permissions.html | 13 +
.../nl_NL/help/help_virtual_links.html | 13 +
.../piwigo/language/nl_NL/help/history.html | 37 +
.../piwigo/language/nl_NL/help/index.php | 15 +
.../language/nl_NL/help/maintenance.html | 54 +
.../nl_NL/help/notification_by_mail.html | 15 +
.../language/nl_NL/help/permalinks.html | 7 +
.../language/nl_NL/help/photos_add_ftp.html | 120 +
.../language/nl_NL/help/quick_search.html | 141 +
.../piwigo/language/nl_NL/help/search.html | 19 +
.../language/nl_NL/help/synchronize.html | 8 +
.../piwigo/language/nl_NL/help/user_list.html | 30 +
.../language/nl_NL/help_quick_search.lang.php | 57 +
.../piwigo/language/nl_NL/index.php | 15 +
.../piwigo/language/nl_NL/install.lang.php | 53 +
.../piwigo-data/piwigo/language/nl_NL/iso.txt | 1 +
.../piwigo/language/nl_NL/nl_NL.jpg | Bin 0 -> 1181 bytes
.../piwigo/language/nl_NL/upgrade.lang.php | 27 +
.../language/nl_NL/whats_new_15.lang.php | 11 +
.../language/nl_NL/whats_new_16.lang.php | 10 +
.../piwigo/language/nn_NO/about.html | 5 +
.../piwigo/language/nn_NO/admin.lang.php | 962 +
.../piwigo/language/nn_NO/common.lang.php | 416 +
.../language/nn_NO/help/cat_modify.html | 118 +
.../piwigo/language/nn_NO/help/cat_move.html | 14 +
.../language/nn_NO/help/cat_options.html | 22 +
.../piwigo/language/nn_NO/help/cat_perm.html | 11 +
.../language/nn_NO/help/help_add_photos.html | 21 +
.../language/nn_NO/help/help_groups.html | 11 +
.../piwigo/language/nn_NO/help/help_misc.html | 9 +
.../nn_NO/help/help_virtual_links.html | 12 +
.../piwigo/language/nn_NO/help/history.html | 22 +
.../nn_NO/help/notification_by_mail.html | 14 +
.../language/nn_NO/help/permalinks.html | 7 +
.../language/nn_NO/help/photos_add_ftp.html | 77 +
.../piwigo/language/nn_NO/help/search.html | 23 +
.../language/nn_NO/help/synchronize.html | 14 +
.../piwigo/language/nn_NO/help/user_list.html | 23 +
.../piwigo/language/nn_NO/install.lang.php | 52 +
.../piwigo-data/piwigo/language/nn_NO/iso.txt | 1 +
.../piwigo/language/nn_NO/nn_NO.jpg | Bin 0 -> 1276 bytes
.../piwigo/language/nn_NO/upgrade.lang.php | 25 +
.../piwigo/language/pl_PL/about.html | 6 +
.../piwigo/language/pl_PL/admin.lang.php | 1429 ++
.../piwigo/language/pl_PL/common.lang.php | 559 +
.../language/pl_PL/help/cat_modify.html | 118 +
.../piwigo/language/pl_PL/help/cat_move.html | 14 +
.../language/pl_PL/help/cat_options.html | 27 +
.../piwigo/language/pl_PL/help/cat_perm.html | 11 +
.../language/pl_PL/help/configuration.html | 109 +
.../pl_PL/help/extend_for_templates.html | 87 +
.../language/pl_PL/help/group_list.html | 22 +
.../language/pl_PL/help/help_add_photos.html | 21 +
.../language/pl_PL/help/help_groups.html | 5 +
.../piwigo/language/pl_PL/help/help_misc.html | 9 +
.../language/pl_PL/help/help_permissions.html | 46 +
.../pl_PL/help/help_virtual_links.html | 5 +
.../piwigo/language/pl_PL/help/history.html | 38 +
.../piwigo/language/pl_PL/help/index.php | 15 +
.../language/pl_PL/help/maintenance.html | 47 +
.../pl_PL/help/notification_by_mail.html | 15 +
.../language/pl_PL/help/permalinks.html | 7 +
.../language/pl_PL/help/photos_add_ftp.html | 81 +
.../language/pl_PL/help/quick_search.html | 141 +
.../piwigo/language/pl_PL/help/search.html | 19 +
.../language/pl_PL/help/synchronize.html | 8 +
.../piwigo/language/pl_PL/help/user_list.html | 30 +
.../language/pl_PL/help_quick_search.lang.php | 57 +
.../piwigo/language/pl_PL/index.php | 15 +
.../piwigo/language/pl_PL/install.lang.php | 53 +
.../piwigo-data/piwigo/language/pl_PL/iso.txt | 1 +
.../piwigo/language/pl_PL/pl_PL.jpg | Bin 0 -> 1132 bytes
.../piwigo/language/pl_PL/upgrade.lang.php | 27 +
.../language/pl_PL/whats_new_15.lang.php | 11 +
.../language/pl_PL/whats_new_16.lang.php | 10 +
.../piwigo/language/pt_BR/about.html | 6 +
.../piwigo/language/pt_BR/admin.lang.php | 1432 ++
.../piwigo/language/pt_BR/common.lang.php | 538 +
.../language/pt_BR/help/cat_modify.html | 123 +
.../piwigo/language/pt_BR/help/cat_move.html | 15 +
.../language/pt_BR/help/cat_options.html | 22 +
.../piwigo/language/pt_BR/help/cat_perm.html | 14 +
.../language/pt_BR/help/configuration.html | 101 +
.../pt_BR/help/extend_for_templates.html | 51 +
.../language/pt_BR/help/group_list.html | 22 +
.../language/pt_BR/help/help_add_photos.html | 27 +
.../language/pt_BR/help/help_groups.html | 6 +
.../piwigo/language/pt_BR/help/help_misc.html | 4 +
.../language/pt_BR/help/help_permissions.html | 12 +
.../pt_BR/help/help_virtual_links.html | 6 +
.../piwigo/language/pt_BR/help/history.html | 22 +
.../language/pt_BR/help/maintenance.html | 26 +
.../pt_BR/help/notification_by_mail.html | 14 +
.../language/pt_BR/help/permalinks.html | 7 +
.../language/pt_BR/help/photos_add_ftp.html | 85 +
.../language/pt_BR/help/quick_search.html | 141 +
.../piwigo/language/pt_BR/help/search.html | 24 +
.../language/pt_BR/help/synchronize.html | 14 +
.../piwigo/language/pt_BR/help/user_list.html | 23 +
.../language/pt_BR/help_quick_search.lang.php | 57 +
.../piwigo/language/pt_BR/index.php | 15 +
.../piwigo/language/pt_BR/install.lang.php | 54 +
.../piwigo-data/piwigo/language/pt_BR/iso.txt | 1 +
.../piwigo/language/pt_BR/pt_BR.jpg | Bin 0 -> 1056 bytes
.../piwigo/language/pt_BR/upgrade.lang.php | 29 +
.../language/pt_BR/whats_new_15.lang.php | 11 +
.../language/pt_BR/whats_new_16.lang.php | 10 +
.../piwigo/language/pt_PT/about.html | 5 +
.../piwigo/language/pt_PT/admin.lang.php | 1433 ++
.../piwigo/language/pt_PT/common.lang.php | 541 +
.../language/pt_PT/help/cat_modify.html | 111 +
.../piwigo/language/pt_PT/help/cat_move.html | 14 +
.../language/pt_PT/help/cat_options.html | 23 +
.../piwigo/language/pt_PT/help/cat_perm.html | 11 +
.../language/pt_PT/help/configuration.html | 98 +
.../pt_PT/help/extend_for_templates.html | 51 +
.../language/pt_PT/help/group_list.html | 22 +
.../language/pt_PT/help/help_add_photos.html | 29 +
.../language/pt_PT/help/help_groups.html | 6 +
.../piwigo/language/pt_PT/help/help_misc.html | 4 +
.../language/pt_PT/help/help_permissions.html | 12 +
.../pt_PT/help/help_virtual_links.html | 6 +
.../piwigo/language/pt_PT/help/history.html | 22 +
.../language/pt_PT/help/maintenance.html | 26 +
.../pt_PT/help/notification_by_mail.html | 14 +
.../language/pt_PT/help/permalinks.html | 7 +
.../language/pt_PT/help/photos_add_ftp.html | 76 +
.../piwigo/language/pt_PT/help/search.html | 20 +
.../language/pt_PT/help/synchronize.html | 14 +
.../piwigo/language/pt_PT/help/user_list.html | 23 +
.../language/pt_PT/help_quick_search.lang.php | 57 +
.../piwigo/language/pt_PT/index.php | 15 +
.../piwigo/language/pt_PT/install.lang.php | 55 +
.../piwigo-data/piwigo/language/pt_PT/iso.txt | 1 +
.../piwigo/language/pt_PT/pt_PT.jpg | Bin 0 -> 1139 bytes
.../piwigo/language/pt_PT/upgrade.lang.php | 27 +
.../language/pt_PT/whats_new_16.lang.php | 10 +
.../piwigo/language/ro_RO/about.html | 8 +
.../piwigo/language/ro_RO/admin.lang.php | 1331 +
.../piwigo/language/ro_RO/common.lang.php | 450 +
.../language/ro_RO/help/cat_modify.html | 133 +
.../piwigo/language/ro_RO/help/cat_move.html | 11 +
.../language/ro_RO/help/cat_options.html | 22 +
.../language/ro_RO/help/help_add_photos.html | 27 +
.../language/ro_RO/help/help_groups.html | 11 +
.../piwigo/language/ro_RO/help/help_misc.html | 9 +
.../piwigo/language/ro_RO/index.php | 15 +
.../piwigo/language/ro_RO/install.lang.php | 53 +
.../piwigo-data/piwigo/language/ro_RO/iso.txt | 1 +
.../piwigo/language/ro_RO/ro_RO.jpg | Bin 0 -> 1079 bytes
.../piwigo/language/ro_RO/upgrade.lang.php | 26 +
.../piwigo/language/ru_RU/about.html | 6 +
.../piwigo/language/ru_RU/admin.lang.php | 1373 +
.../piwigo/language/ru_RU/common.lang.php | 540 +
.../language/ru_RU/help/cat_modify.html | 137 +
.../piwigo/language/ru_RU/help/cat_move.html | 14 +
.../language/ru_RU/help/cat_options.html | 34 +
.../piwigo/language/ru_RU/help/cat_perm.html | 15 +
.../language/ru_RU/help/configuration.html | 136 +
.../ru_RU/help/extend_for_templates.html | 96 +
.../language/ru_RU/help/group_list.html | 22 +
.../language/ru_RU/help/help_add_photos.html | 22 +
.../language/ru_RU/help/help_groups.html | 6 +
.../piwigo/language/ru_RU/help/help_misc.html | 9 +
.../language/ru_RU/help/help_permissions.html | 45 +
.../ru_RU/help/help_virtual_links.html | 8 +
.../piwigo/language/ru_RU/help/history.html | 45 +
.../piwigo/language/ru_RU/help/index.php | 15 +
.../language/ru_RU/help/maintenance.html | 60 +
.../ru_RU/help/notification_by_mail.html | 16 +
.../language/ru_RU/help/permalinks.html | 12 +
.../language/ru_RU/help/photos_add_ftp.html | 80 +
.../language/ru_RU/help/quick_search.html | 141 +
.../piwigo/language/ru_RU/help/search.html | 22 +
.../language/ru_RU/help/synchronize.html | 12 +
.../piwigo/language/ru_RU/help/user_list.html | 32 +
.../piwigo/language/ru_RU/index.php | 15 +
.../piwigo/language/ru_RU/install.lang.php | 53 +
.../piwigo-data/piwigo/language/ru_RU/iso.txt | 1 +
.../piwigo/language/ru_RU/ru_RU.jpg | Bin 0 -> 489 bytes
.../piwigo/language/ru_RU/upgrade.lang.php | 26 +
.../language/ru_RU/whats_new_15.lang.php | 11 +
.../language/ru_RU/whats_new_16.lang.php | 10 +
.../piwigo/language/sh_RS/about.html | 5 +
.../piwigo/language/sh_RS/admin.lang.php | 883 +
.../piwigo/language/sh_RS/common.lang.php | 411 +
.../language/sh_RS/help/cat_modify.html | 129 +
.../language/sh_RS/help/help_add_photos.html | 25 +
.../piwigo/language/sh_RS/help/index.php | 15 +
.../piwigo/language/sh_RS/index.php | 15 +
.../piwigo/language/sh_RS/install.lang.php | 52 +
.../piwigo-data/piwigo/language/sh_RS/iso.txt | 1 +
.../piwigo/language/sh_RS/sh_RS.jpg | Bin 0 -> 820 bytes
.../piwigo/language/sh_RS/sr_RS.jpg | Bin 0 -> 820 bytes
.../piwigo/language/sh_RS/upgrade.lang.php | 29 +
.../piwigo/language/sk_SK/about.html | 5 +
.../piwigo/language/sk_SK/admin.lang.php | 1429 ++
.../piwigo/language/sk_SK/common.lang.php | 543 +
.../language/sk_SK/help/cat_modify.html | 117 +
.../piwigo/language/sk_SK/help/cat_move.html | 14 +
.../language/sk_SK/help/cat_options.html | 22 +
.../piwigo/language/sk_SK/help/cat_perm.html | 11 +
.../language/sk_SK/help/configuration.html | 100 +
.../sk_SK/help/extend_for_templates.html | 55 +
.../language/sk_SK/help/group_list.html | 21 +
.../language/sk_SK/help/help_add_photos.html | 22 +
.../language/sk_SK/help/help_groups.html | 8 +
.../piwigo/language/sk_SK/help/help_misc.html | 9 +
.../language/sk_SK/help/help_permissions.html | 54 +
.../sk_SK/help/help_virtual_links.html | 6 +
.../piwigo/language/sk_SK/help/history.html | 31 +
.../piwigo/language/sk_SK/help/index.php | 15 +
.../language/sk_SK/help/maintenance.html | 32 +
.../sk_SK/help/notification_by_mail.html | 14 +
.../language/sk_SK/help/permalinks.html | 8 +
.../language/sk_SK/help/photos_add_ftp.html | 80 +
.../piwigo/language/sk_SK/help/search.html | 19 +
.../language/sk_SK/help/synchronize.html | 14 +
.../piwigo/language/sk_SK/help/user_list.html | 26 +
.../language/sk_SK/help_quick_search.lang.php | 57 +
.../piwigo/language/sk_SK/index.php | 15 +
.../piwigo/language/sk_SK/install.lang.php | 53 +
.../piwigo-data/piwigo/language/sk_SK/iso.txt | 1 +
.../piwigo/language/sk_SK/sk_SK.jpg | Bin 0 -> 1117 bytes
.../piwigo/language/sk_SK/upgrade.lang.php | 28 +
.../language/sk_SK/whats_new_15.lang.php | 11 +
.../language/sk_SK/whats_new_16.lang.php | 10 +
.../piwigo/language/sl_SI/about.html | 7 +
.../piwigo/language/sl_SI/admin.lang.php | 1253 +
.../piwigo/language/sl_SI/common.lang.php | 419 +
.../language/sl_SI/help/cat_modify.html | 133 +
.../piwigo/language/sl_SI/help/cat_move.html | 14 +
.../language/sl_SI/help/cat_options.html | 22 +
.../piwigo/language/sl_SI/help/cat_perm.html | 13 +
.../language/sl_SI/help/configuration.html | 101 +
.../language/sl_SI/help/group_list.html | 22 +
.../language/sl_SI/help/help_add_photos.html | 27 +
.../language/sl_SI/help/help_groups.html | 11 +
.../piwigo/language/sl_SI/help/help_misc.html | 9 +
.../language/sl_SI/help/help_permissions.html | 57 +
.../sl_SI/help/help_virtual_links.html | 12 +
.../piwigo/language/sl_SI/help/history.html | 22 +
.../sl_SI/help/notification_by_mail.html | 15 +
.../language/sl_SI/help/permalinks.html | 7 +
.../language/sl_SI/help/quick_search.html | 141 +
.../piwigo/language/sl_SI/help/search.html | 24 +
.../language/sl_SI/help/synchronize.html | 14 +
.../piwigo/language/sl_SI/help/user_list.html | 23 +
.../piwigo/language/sl_SI/index.php | 7 +
.../piwigo/language/sl_SI/install.lang.php | 53 +
.../piwigo-data/piwigo/language/sl_SI/iso.txt | 1 +
.../piwigo/language/sl_SI/sl_SI.jpg | Bin 0 -> 453 bytes
.../piwigo/language/sl_SI/upgrade.lang.php | 25 +
.../piwigo/language/sr_RS/about.html | 6 +
.../piwigo/language/sr_RS/admin.lang.php | 1402 +
.../piwigo/language/sr_RS/common.lang.php | 458 +
.../piwigo/language/sr_RS/help/cat_move.html | 14 +
.../language/sr_RS/help/group_list.html | 22 +
.../language/sr_RS/help/help_groups.html | 8 +
.../piwigo/language/sr_RS/help/search.html | 24 +
.../language/sr_RS/help_quick_search.lang.php | 57 +
.../piwigo/language/sr_RS/index.php | 15 +
.../piwigo/language/sr_RS/install.lang.php | 53 +
.../piwigo-data/piwigo/language/sr_RS/iso.txt | 1 +
.../piwigo/language/sr_RS/sr_RS.jpg | Bin 0 -> 820 bytes
.../piwigo/language/sr_RS/upgrade.lang.php | 29 +
.../language/sr_RS/whats_new_15.lang.php | 11 +
.../piwigo/language/sv_SE/about.html | 5 +
.../piwigo/language/sv_SE/admin.lang.php | 1430 ++
.../piwigo/language/sv_SE/common.lang.php | 537 +
.../language/sv_SE/help/cat_modify.html | 130 +
.../piwigo/language/sv_SE/help/cat_move.html | 14 +
.../language/sv_SE/help/cat_options.html | 22 +
.../piwigo/language/sv_SE/help/cat_perm.html | 13 +
.../language/sv_SE/help/configuration.html | 132 +
.../sv_SE/help/extend_for_templates.html | 54 +
.../language/sv_SE/help/group_list.html | 22 +
.../language/sv_SE/help/help_add_photos.html | 27 +
.../language/sv_SE/help/help_groups.html | 11 +
.../piwigo/language/sv_SE/help/help_misc.html | 10 +
.../language/sv_SE/help/help_permissions.html | 57 +
.../sv_SE/help/help_virtual_links.html | 6 +
.../piwigo/language/sv_SE/help/history.html | 22 +
.../piwigo/language/sv_SE/help/index.php | 15 +
.../language/sv_SE/help/maintenance.html | 26 +
.../sv_SE/help/notification_by_mail.html | 15 +
.../language/sv_SE/help/permalinks.html | 7 +
.../language/sv_SE/help/photos_add_ftp.html | 82 +
.../language/sv_SE/help/quick_search.html | 141 +
.../piwigo/language/sv_SE/help/search.html | 24 +
.../language/sv_SE/help/synchronize.html | 14 +
.../piwigo/language/sv_SE/help/user_list.html | 33 +
.../language/sv_SE/help_quick_search.lang.php | 57 +
.../piwigo/language/sv_SE/install.lang.php | 53 +
.../piwigo-data/piwigo/language/sv_SE/iso.txt | 1 +
.../piwigo/language/sv_SE/sv_SE.jpg | Bin 0 -> 1210 bytes
.../piwigo/language/sv_SE/upgrade.lang.php | 28 +
.../language/sv_SE/whats_new_15.lang.php | 11 +
.../language/sv_SE/whats_new_16.lang.php | 10 +
.../piwigo/language/ta_IN/admin.lang.php | 184 +
.../piwigo/language/ta_IN/common.lang.php | 417 +
.../piwigo/language/ta_IN/install.lang.php | 56 +
.../piwigo-data/piwigo/language/ta_IN/iso.txt | 1 +
.../piwigo/language/ta_IN/ta_IN.jpg | Bin 0 -> 1094 bytes
.../piwigo/language/ta_IN/upgrade.lang.php | 28 +
.../piwigo/language/te_IN/common.lang.php | 20 +
.../piwigo-data/piwigo/language/te_IN/iso.txt | 1 +
.../piwigo/language/te_IN/te_IN.jpg | Bin 0 -> 1094 bytes
.../piwigo/language/th_TH/about.html | 5 +
.../piwigo/language/th_TH/admin.lang.php | 999 +
.../piwigo/language/th_TH/common.lang.php | 416 +
.../piwigo/language/th_TH/help/index.php | 7 +
.../piwigo/language/th_TH/help/user_list.html | 23 +
.../piwigo/language/th_TH/install.lang.php | 52 +
.../piwigo-data/piwigo/language/th_TH/iso.txt | 1 +
.../piwigo/language/th_TH/th_TH.jpg | Bin 0 -> 657 bytes
.../piwigo/language/th_TH/upgrade.lang.php | 28 +
.../piwigo/language/tr_TR/about.html | 5 +
.../piwigo/language/tr_TR/admin.lang.php | 1427 ++
.../piwigo/language/tr_TR/common.lang.php | 537 +
.../language/tr_TR/help/cat_modify.html | 126 +
.../piwigo/language/tr_TR/help/cat_move.html | 14 +
.../language/tr_TR/help/cat_options.html | 21 +
.../piwigo/language/tr_TR/help/cat_perm.html | 11 +
.../language/tr_TR/help/configuration.html | 117 +
.../tr_TR/help/extend_for_templates.html | 55 +
.../language/tr_TR/help/group_list.html | 22 +
.../language/tr_TR/help/help_add_photos.html | 26 +
.../language/tr_TR/help/help_groups.html | 10 +
.../piwigo/language/tr_TR/help/help_misc.html | 9 +
.../language/tr_TR/help/help_permissions.html | 54 +
.../tr_TR/help/help_virtual_links.html | 9 +
.../piwigo/language/tr_TR/help/history.html | 22 +
.../language/tr_TR/help/maintenance.html | 25 +
.../tr_TR/help/notification_by_mail.html | 15 +
.../language/tr_TR/help/permalinks.html | 7 +
.../language/tr_TR/help/photos_add_ftp.html | 79 +
.../language/tr_TR/help/quick_search.html | 141 +
.../piwigo/language/tr_TR/help/search.html | 19 +
.../language/tr_TR/help/synchronize.html | 13 +
.../piwigo/language/tr_TR/help/user_list.html | 25 +
.../language/tr_TR/help_quick_search.lang.php | 58 +
.../piwigo/language/tr_TR/install.lang.php | 54 +
.../piwigo-data/piwigo/language/tr_TR/iso.txt | 1 +
.../piwigo/language/tr_TR/tr_TR.jpg | Bin 0 -> 1131 bytes
.../piwigo/language/tr_TR/upgrade.lang.php | 27 +
.../language/tr_TR/whats_new_15.lang.php | 11 +
.../language/tr_TR/whats_new_16.lang.php | 10 +
.../piwigo/language/uk_UA/about.html | 9 +
.../piwigo/language/uk_UA/admin.lang.php | 1347 +
.../piwigo/language/uk_UA/common.lang.php | 447 +
.../language/uk_UA/help/cat_modify.html | 128 +
.../piwigo/language/uk_UA/help/cat_move.html | 14 +
.../language/uk_UA/help/cat_options.html | 22 +
.../piwigo/language/uk_UA/help/cat_perm.html | 13 +
.../language/uk_UA/help/configuration.html | 101 +
.../uk_UA/help/extend_for_templates.html | 51 +
.../language/uk_UA/help/group_list.html | 22 +
.../language/uk_UA/help/help_add_photos.html | 27 +
.../language/uk_UA/help/help_groups.html | 11 +
.../piwigo/language/uk_UA/help/help_misc.html | 9 +
.../language/uk_UA/help/help_permissions.html | 58 +
.../uk_UA/help/help_virtual_links.html | 11 +
.../piwigo/language/uk_UA/help/history.html | 22 +
.../language/uk_UA/help/maintenance.html | 26 +
.../uk_UA/help/notification_by_mail.html | 14 +
.../language/uk_UA/help/permalinks.html | 7 +
.../language/uk_UA/help/photos_add_ftp.html | 81 +
.../language/uk_UA/help/quick_search.html | 141 +
.../piwigo/language/uk_UA/help/search.html | 23 +
.../language/uk_UA/help/synchronize.html | 14 +
.../piwigo/language/uk_UA/help/user_list.html | 23 +
.../piwigo/language/uk_UA/install.lang.php | 53 +
.../piwigo-data/piwigo/language/uk_UA/iso.txt | 1 +
.../piwigo/language/uk_UA/uk_UA.jpg | Bin 0 -> 997 bytes
.../piwigo/language/uk_UA/upgrade.lang.php | 25 +
.../piwigo/language/vi_VN/README.txt | 6 +
.../piwigo/language/vi_VN/about.html | 8 +
.../piwigo/language/vi_VN/admin.lang.php | 997 +
.../piwigo/language/vi_VN/common.lang.php | 421 +
.../language/vi_VN/help/group_list.html | 22 +
.../language/vi_VN/help/help_add_photos.html | 23 +
.../piwigo/language/vi_VN/help/help_misc.html | 9 +
.../piwigo/language/vi_VN/help/index.php | 15 +
.../language/vi_VN/help/quick_search.html | 141 +
.../piwigo/language/vi_VN/install.lang.php | 54 +
.../piwigo-data/piwigo/language/vi_VN/iso.txt | 1 +
.../piwigo/language/vi_VN/upgrade.lang.php | 27 +
.../piwigo/language/vi_VN/vi_VN.jpg | Bin 0 -> 1072 bytes
.../language/vi_VN/whats_new_15.lang.php | 8 +
.../piwigo/language/wo_SN/common.lang.php | 42 +
.../piwigo-data/piwigo/language/wo_SN/iso.txt | 1 +
.../piwigo/language/wo_SN/wo_SN.jpg | Bin 0 -> 358 bytes
.../piwigo/language/zh_CN/about.html | 7 +
.../piwigo/language/zh_CN/admin.lang.php | 1436 ++
.../piwigo/language/zh_CN/common.lang.php | 540 +
.../language/zh_CN/help/cat_modify.html | 126 +
.../piwigo/language/zh_CN/help/cat_move.html | 14 +
.../language/zh_CN/help/cat_options.html | 22 +
.../piwigo/language/zh_CN/help/cat_perm.html | 11 +
.../language/zh_CN/help/configuration.html | 103 +
.../zh_CN/help/extend_for_templates.html | 51 +
.../language/zh_CN/help/group_list.html | 22 +
.../language/zh_CN/help/help_add_photos.html | 21 +
.../language/zh_CN/help/help_groups.html | 6 +
.../piwigo/language/zh_CN/help/help_misc.html | 4 +
.../language/zh_CN/help/help_permissions.html | 50 +
.../zh_CN/help/help_virtual_links.html | 6 +
.../piwigo/language/zh_CN/help/history.html | 22 +
.../language/zh_CN/help/maintenance.html | 52 +
.../zh_CN/help/notification_by_mail.html | 15 +
.../language/zh_CN/help/permalinks.html | 7 +
.../language/zh_CN/help/photos_add_ftp.html | 77 +
.../language/zh_CN/help/quick_search.html | 141 +
.../piwigo/language/zh_CN/help/search.html | 19 +
.../language/zh_CN/help/synchronize.html | 11 +
.../piwigo/language/zh_CN/help/user_list.html | 23 +
.../language/zh_CN/help_quick_search.lang.php | 57 +
.../piwigo/language/zh_CN/install.lang.php | 55 +
.../piwigo-data/piwigo/language/zh_CN/iso.txt | 1 +
.../piwigo/language/zh_CN/upgrade.lang.php | 27 +
.../language/zh_CN/whats_new_15.lang.php | 11 +
.../language/zh_CN/whats_new_16.lang.php | 10 +
.../piwigo/language/zh_CN/zh_CN.jpg | Bin 0 -> 1080 bytes
.../piwigo/language/zh_HK/about.html | 6 +
.../piwigo/language/zh_HK/admin.lang.php | 978 +
.../piwigo/language/zh_HK/common.lang.php | 421 +
.../piwigo/language/zh_HK/help/cat_move.html | 14 +
.../language/zh_HK/help/cat_options.html | 20 +
.../piwigo/language/zh_HK/help/cat_perm.html | 11 +
.../piwigo/language/zh_HK/help/index.php | 7 +
.../piwigo/language/zh_HK/index.php | 15 +
.../piwigo/language/zh_HK/install.lang.php | 52 +
.../piwigo-data/piwigo/language/zh_HK/iso.txt | 1 +
.../piwigo/language/zh_HK/upgrade.lang.php | 25 +
.../piwigo/language/zh_HK/zh_HK.jpg | Bin 0 -> 1001 bytes
.../piwigo/language/zh_TW/about.html | 7 +
.../piwigo/language/zh_TW/admin.lang.php | 1427 ++
.../piwigo/language/zh_TW/common.lang.php | 538 +
.../language/zh_TW/help/cat_modify.html | 127 +
.../piwigo/language/zh_TW/help/cat_move.html | 14 +
.../language/zh_TW/help/cat_options.html | 22 +
.../piwigo/language/zh_TW/help/cat_perm.html | 14 +
.../language/zh_TW/help/configuration.html | 107 +
.../zh_TW/help/extend_for_templates.html | 71 +
.../language/zh_TW/help/group_list.html | 21 +
.../language/zh_TW/help/help_add_photos.html | 23 +
.../language/zh_TW/help/help_groups.html | 12 +
.../piwigo/language/zh_TW/help/help_misc.html | 9 +
.../language/zh_TW/help/help_permissions.html | 56 +
.../zh_TW/help/help_virtual_links.html | 7 +
.../piwigo/language/zh_TW/help/history.html | 23 +
.../language/zh_TW/help/maintenance.html | 32 +
.../zh_TW/help/notification_by_mail.html | 14 +
.../language/zh_TW/help/permalinks.html | 7 +
.../language/zh_TW/help/photos_add_ftp.html | 81 +
.../language/zh_TW/help/quick_search.html | 141 +
.../piwigo/language/zh_TW/help/search.html | 21 +
.../language/zh_TW/help/synchronize.html | 14 +
.../piwigo/language/zh_TW/help/user_list.html | 23 +
.../language/zh_TW/help_quick_search.lang.php | 57 +
.../piwigo/language/zh_TW/install.lang.php | 54 +
.../piwigo-data/piwigo/language/zh_TW/iso.txt | 1 +
.../piwigo/language/zh_TW/upgrade.lang.php | 29 +
.../language/zh_TW/whats_new_15.lang.php | 11 +
.../language/zh_TW/whats_new_16.lang.php | 10 +
.../piwigo/language/zh_TW/zh_TW.jpg | Bin 0 -> 1011 bytes
Piwingo/piwigo-data/piwigo/local/index.php | 15 +
Piwingo/piwigo-data/piwigo/nbm.php | 66 +
Piwingo/piwigo-data/piwigo/notification.php | 107 +
Piwingo/piwigo-data/piwigo/password.php | 538 +
Piwingo/piwigo-data/piwigo/picture.php | 1033 +
Piwingo/piwigo-data/piwigo/plugins/index.php | 15 +
Piwingo/piwigo-data/piwigo/popuphelp.php | 66 +
Piwingo/piwigo-data/piwigo/profile.php | 441 +
Piwingo/piwigo-data/piwigo/qsearch.php | 23 +
Piwingo/piwigo-data/piwigo/random.php | 48 +
Piwingo/piwigo-data/piwigo/register.php | 144 +
Piwingo/piwigo-data/piwigo/search.php | 191 +
Piwingo/piwigo-data/piwigo/tags.php | 168 +
.../distributed/samples/my-picture.tpl | 122 +
.../distributed/samples/my-thumbnails.tpl | 35 +
.../distributed/samples/my-thumbnails2.css | 13 +
.../distributed/samples/my-thumbnails2.tpl | 18 +
.../samples/titling_categories.tpl | 50 +
.../piwigo/template-extension/index.php | 15 +
.../piwigo/template-extension/yoga/index.php | 15 +
.../template-extension/yoga/local/README | 19 +
.../template-extension/yoga/local/index.php | 15 +
.../themes/default/css/clear-search.css | 347 +
.../piwigo/themes/default/css/dark-search.css | 335 +
.../themes/default/css/help/quick_search.css | 68 +
.../piwigo/themes/default/css/search.css | 1070 +
.../piwigo/themes/default/fix-ie5-ie6.css | 72 +
.../piwigo/themes/default/fix-ie7.css | 29 +
.../piwigo/themes/default/fix-khtml.css | 17 +
.../piwigo/themes/default/icon/datepicker.png | Bin 0 -> 1047 bytes
.../piwigo/themes/default/icon/errors.png | Bin 0 -> 3249 bytes
.../themes/default/icon/errors_small.png | Bin 0 -> 1270 bytes
.../piwigo/themes/default/icon/favicon.ico | Bin 0 -> 15086 bytes
.../piwigo/themes/default/icon/img_small.png | Bin 0 -> 1164 bytes
.../piwigo/themes/default/icon/index.php | 15 +
.../piwigo/themes/default/icon/infos.png | Bin 0 -> 2250 bytes
.../default/icon/mimetypes/afdesign.png | Bin 0 -> 8878 bytes
.../themes/default/icon/mimetypes/afphoto.png | Bin 0 -> 8638 bytes
.../themes/default/icon/mimetypes/afpub.png | Bin 0 -> 8695 bytes
.../themes/default/icon/mimetypes/ai.png | Bin 0 -> 7009 bytes
.../themes/default/icon/mimetypes/avi.png | Bin 0 -> 8071 bytes
.../themes/default/icon/mimetypes/doc.png | Bin 0 -> 9491 bytes
.../themes/default/icon/mimetypes/docx.png | Bin 0 -> 10510 bytes
.../themes/default/icon/mimetypes/idml.png | Bin 0 -> 7974 bytes
.../themes/default/icon/mimetypes/indd.png | Bin 0 -> 8178 bytes
.../themes/default/icon/mimetypes/index.php | 15 +
.../themes/default/icon/mimetypes/mov.png | Bin 0 -> 9617 bytes
.../themes/default/icon/mimetypes/mp3.png | Bin 0 -> 8591 bytes
.../themes/default/icon/mimetypes/mp4.png | Bin 0 -> 8132 bytes
.../themes/default/icon/mimetypes/mpg.png | Bin 0 -> 8943 bytes
.../themes/default/icon/mimetypes/ogg.png | Bin 0 -> 9405 bytes
.../themes/default/icon/mimetypes/ppt.png | Bin 0 -> 7298 bytes
.../themes/default/icon/mimetypes/pptx.png | Bin 0 -> 8731 bytes
.../themes/default/icon/mimetypes/prpoj.png | Bin 0 -> 9422 bytes
.../themes/default/icon/mimetypes/psd.png | Bin 0 -> 8578 bytes
.../themes/default/icon/mimetypes/txt.png | Bin 0 -> 7397 bytes
.../themes/default/icon/mimetypes/unknown.png | Bin 0 -> 9958 bytes
.../themes/default/icon/mimetypes/xd.png | Bin 0 -> 8114 bytes
.../themes/default/icon/mimetypes/xls.png | Bin 0 -> 8976 bytes
.../themes/default/icon/mimetypes/xlsx.png | Bin 0 -> 9879 bytes
.../themes/default/icon/mimetypes/zip.png | Bin 0 -> 7264 bytes
.../piwigo/themes/default/icon/note.png | Bin 0 -> 1862 bytes
.../themes/default/icon/piwigo.org-icon 1.svg | 7 +
.../themes/default/icon/rating-stars.gif | Bin 0 -> 1065 bytes
.../piwigo/themes/default/icon/recent.png | Bin 0 -> 757 bytes
.../themes/default/icon/recent_by_child.png | Bin 0 -> 738 bytes
.../piwigo/themes/default/icon/remove_s.png | Bin 0 -> 323 bytes
.../themes/default/icon/warning-triangle.svg | 3 +
.../piwigo/themes/default/iconset.css | 72 +
.../default/images/ajax-loader-small.gif | Bin 0 -> 723 bytes
.../themes/default/images/ajax_loader.gif | Bin 0 -> 10819 bytes
.../piwigo/themes/default/images/index.php | 15 +
.../themes/default/images/progressbar.gif | Bin 0 -> 120 bytes
.../default/images/progressbg_black.gif | Bin 0 -> 1626 bytes
.../default/images/progressbg_green.gif | Bin 0 -> 1308 bytes
.../default/images/progressbg_orange.gif | Bin 0 -> 1308 bytes
.../themes/default/images/progressbg_red.gif | Bin 0 -> 1308 bytes
.../default/images/progressbg_yellow.gif | Bin 0 -> 1308 bytes
.../piwigo/themes/default/index.php | 15 +
.../piwigo/themes/default/js/jquery.cookie.js | 117 +
.../piwigo/themes/default/js/jquery.js | 10351 ++++++++
.../piwigo/themes/default/js/jquery.min.js | 5 +
.../piwigo/themes/default/js/mcs.js | 1728 ++
.../themes/default/js/plugins/Chart.min.css | 1 +
.../themes/default/js/plugins/Chart.min.js | 7 +
.../themes/default/js/plugins/Jcrop.gif | Bin 0 -> 329 bytes
.../default/js/plugins/chosen-sprite.png | Bin 0 -> 646 bytes
.../default/js/plugins/chosen-sprite@2x.png | Bin 0 -> 872 bytes
.../themes/default/js/plugins/chosen.css | 430 +
.../default/js/plugins/chosen.jquery.min.js | 2 +
.../colorbox/i18n/jquery.colorbox-ar.js | 15 +
.../colorbox/i18n/jquery.colorbox-bg.js | 16 +
.../colorbox/i18n/jquery.colorbox-bn.js | 16 +
.../colorbox/i18n/jquery.colorbox-ca.js | 13 +
.../colorbox/i18n/jquery.colorbox-cs.js | 16 +
.../colorbox/i18n/jquery.colorbox-da.js | 16 +
.../colorbox/i18n/jquery.colorbox-de.js | 15 +
.../colorbox/i18n/jquery.colorbox-es.js | 13 +
.../colorbox/i18n/jquery.colorbox-et.js | 15 +
.../colorbox/i18n/jquery.colorbox-fa.js | 18 +
.../colorbox/i18n/jquery.colorbox-fi.js | 15 +
.../colorbox/i18n/jquery.colorbox-fr.js | 15 +
.../colorbox/i18n/jquery.colorbox-gl.js | 13 +
.../colorbox/i18n/jquery.colorbox-gr.js | 16 +
.../colorbox/i18n/jquery.colorbox-he.js | 16 +
.../colorbox/i18n/jquery.colorbox-hr.js | 15 +
.../colorbox/i18n/jquery.colorbox-hu.js | 15 +
.../colorbox/i18n/jquery.colorbox-id.js | 15 +
.../colorbox/i18n/jquery.colorbox-it.js | 15 +
.../colorbox/i18n/jquery.colorbox-ja.js | 15 +
.../colorbox/i18n/jquery.colorbox-kr.js | 15 +
.../colorbox/i18n/jquery.colorbox-lt.js | 15 +
.../colorbox/i18n/jquery.colorbox-lv.js | 16 +
.../colorbox/i18n/jquery.colorbox-my.js | 15 +
.../colorbox/i18n/jquery.colorbox-nl.js | 15 +
.../colorbox/i18n/jquery.colorbox-no.js | 16 +
.../colorbox/i18n/jquery.colorbox-pl.js | 16 +
.../colorbox/i18n/jquery.colorbox-pt_BR.js | 15 +
.../colorbox/i18n/jquery.colorbox-ro.js | 15 +
.../colorbox/i18n/jquery.colorbox-ru.js | 16 +
.../colorbox/i18n/jquery.colorbox-si.js | 15 +
.../colorbox/i18n/jquery.colorbox-sk.js | 15 +
.../colorbox/i18n/jquery.colorbox-sr.js | 15 +
.../colorbox/i18n/jquery.colorbox-sv.js | 15 +
.../colorbox/i18n/jquery.colorbox-tr.js | 19 +
.../colorbox/i18n/jquery.colorbox-uk.js | 16 +
.../colorbox/i18n/jquery.colorbox-zh_CN.js | 15 +
.../colorbox/i18n/jquery.colorbox-zh_TW.js | 15 +
.../js/plugins/colorbox/style1/colorbox.css | 70 +
.../plugins/colorbox/style1/images/border.png | Bin 0 -> 76 bytes
.../colorbox/style1/images/controls.png | Bin 0 -> 1261 bytes
.../colorbox/style1/images/loading.gif | Bin 0 -> 8685 bytes
.../style1/images/loading_background.png | Bin 0 -> 131 bytes
.../colorbox/style1/images/overlay.png | Bin 0 -> 115 bytes
.../js/plugins/colorbox/style2/colorbox.css | 50 +
.../colorbox/style2/images/controls.png | Bin 0 -> 643 bytes
.../colorbox/style2/images/loading.gif | Bin 0 -> 6244 bytes
.../js/plugins/colorbox/style3/colorbox.css | 45 +
.../colorbox/style3/images/controls.png | Bin 0 -> 1633 bytes
.../colorbox/style3/images/loading.gif | Bin 0 -> 6244 bytes
.../js/plugins/colorbox/style4/colorbox.css | 66 +
.../colorbox/style4/images/border1.png | Bin 0 -> 629 bytes
.../colorbox/style4/images/border2.png | Bin 0 -> 112 bytes
.../colorbox/style4/images/loading.gif | Bin 0 -> 6244 bytes
.../js/plugins/colorbox/style5/colorbox.css | 58 +
.../plugins/colorbox/style5/images/border.png | Bin 0 -> 139 bytes
.../colorbox/style5/images/controls.png | Bin 0 -> 2027 bytes
.../colorbox/style5/images/loading.gif | Bin 0 -> 8685 bytes
.../style5/images/loading_background.png | Bin 0 -> 131 bytes
.../datatables/css/jquery.dataTables.css | 453 +
.../js/plugins/datatables/images/sort_asc.png | Bin 0 -> 1118 bytes
.../datatables/images/sort_asc_disabled.png | Bin 0 -> 1050 bytes
.../plugins/datatables/images/sort_both.png | Bin 0 -> 1136 bytes
.../plugins/datatables/images/sort_desc.png | Bin 0 -> 1127 bytes
.../datatables/images/sort_desc_disabled.png | Bin 0 -> 1045 bytes
.../default/js/plugins/jgrowl-alert.png | Bin 0 -> 2511 bytes
.../default/js/plugins/jgrowl-check.png | Bin 0 -> 2359 bytes
.../default/js/plugins/jgrowl-error.png | Bin 0 -> 2276 bytes
.../themes/default/js/plugins/jqtree.css | 184 +
.../default/js/plugins/jquery-confirm.min.css | 9 +
.../default/js/plugins/jquery-confirm.min.js | 10 +
.../default/js/plugins/jquery.Jcrop.css | 165 +
.../themes/default/js/plugins/jquery.Jcrop.js | 1694 ++
.../default/js/plugins/jquery.Jcrop.min.js | 22 +
.../default/js/plugins/jquery.ajaxmanager.js | 342 +
.../js/plugins/jquery.autogrow-textarea.js | 47 +
.../default/js/plugins/jquery.cluetip.js | 872 +
.../default/js/plugins/jquery.colorbox.min.js | 6 +
.../default/js/plugins/jquery.dataTables.js | 15268 +++++++++++
.../default/js/plugins/jquery.jgrowl.css | 158 +
.../js/plugins/jquery.jgrowl_minimized.js | 4 +
.../default/js/plugins/jquery.progressbar.js | 186 +
.../js/plugins/jquery.progressbar.min.js | 20 +
.../themes/default/js/plugins/jquery.sort.js | 65 +
.../js/plugins/jquery.tipTip.minified.js | 21 +
.../default/js/plugins/jquery.tokeninput.css | 16 +
.../default/js/plugins/jquery.tokeninput.js | 1098 +
.../js/plugins/moment-with-locales.min.js | 2 +
.../themes/default/js/plugins/piecon.js | 189 +
.../default/js/plugins/plupload/Moxie.swf | Bin 0 -> 29349 bytes
.../default/js/plugins/plupload/Moxie.xap | Bin 0 -> 62643 bytes
.../default/js/plugins/plupload/i18n/ar.js | 2 +
.../default/js/plugins/plupload/i18n/az.js | 2 +
.../default/js/plugins/plupload/i18n/bs.js | 2 +
.../default/js/plugins/plupload/i18n/cs.js | 2 +
.../default/js/plugins/plupload/i18n/cy.js | 2 +
.../default/js/plugins/plupload/i18n/da.js | 2 +
.../default/js/plugins/plupload/i18n/de.js | 2 +
.../default/js/plugins/plupload/i18n/el.js | 2 +
.../default/js/plugins/plupload/i18n/en.js | 2 +
.../default/js/plugins/plupload/i18n/es.js | 2 +
.../default/js/plugins/plupload/i18n/et.js | 2 +
.../default/js/plugins/plupload/i18n/fa.js | 2 +
.../default/js/plugins/plupload/i18n/fi.js | 2 +
.../default/js/plugins/plupload/i18n/fr.js | 2 +
.../default/js/plugins/plupload/i18n/he.js | 2 +
.../default/js/plugins/plupload/i18n/hr.js | 2 +
.../default/js/plugins/plupload/i18n/hu.js | 2 +
.../default/js/plugins/plupload/i18n/hy.js | 2 +
.../default/js/plugins/plupload/i18n/id.js | 2 +
.../default/js/plugins/plupload/i18n/it.js | 2 +
.../default/js/plugins/plupload/i18n/ja.js | 2 +
.../default/js/plugins/plupload/i18n/ka.js | 2 +
.../default/js/plugins/plupload/i18n/kk.js | 2 +
.../default/js/plugins/plupload/i18n/km.js | 2 +
.../default/js/plugins/plupload/i18n/ko.js | 2 +
.../default/js/plugins/plupload/i18n/lt.js | 2 +
.../default/js/plugins/plupload/i18n/lv.js | 2 +
.../default/js/plugins/plupload/i18n/mn.js | 2 +
.../default/js/plugins/plupload/i18n/ms.js | 2 +
.../default/js/plugins/plupload/i18n/nl.js | 2 +
.../default/js/plugins/plupload/i18n/pl.js | 2 +
.../default/js/plugins/plupload/i18n/pt_BR.js | 2 +
.../default/js/plugins/plupload/i18n/ro.js | 2 +
.../default/js/plugins/plupload/i18n/ru.js | 2 +
.../default/js/plugins/plupload/i18n/sk.js | 2 +
.../default/js/plugins/plupload/i18n/sq.js | 2 +
.../default/js/plugins/plupload/i18n/sr.js | 2 +
.../default/js/plugins/plupload/i18n/sr_RS.js | 2 +
.../default/js/plugins/plupload/i18n/sv.js | 2 +
.../default/js/plugins/plupload/i18n/th_TH.js | 2 +
.../default/js/plugins/plupload/i18n/tr.js | 2 +
.../default/js/plugins/plupload/i18n/uk_UA.js | 2 +
.../default/js/plugins/plupload/i18n/zh_CN.js | 2 +
.../default/js/plugins/plupload/i18n/zh_TW.js | 2 +
.../css/jquery.plupload.queue.css | 185 +
.../jquery.plupload.queue/img/backgrounds.gif | Bin 0 -> 2977 bytes
.../img/buttons-disabled.png | Bin 0 -> 1292 bytes
.../jquery.plupload.queue/img/buttons.png | Bin 0 -> 1439 bytes
.../jquery.plupload.queue/img/delete.gif | Bin 0 -> 180 bytes
.../jquery.plupload.queue/img/done.gif | Bin 0 -> 1024 bytes
.../jquery.plupload.queue/img/error.gif | Bin 0 -> 994 bytes
.../jquery.plupload.queue/img/throbber.gif | Bin 0 -> 1922 bytes
.../jquery.plupload.queue/img/transp50.png | Bin 0 -> 399 bytes
.../jquery.plupload.queue.js | 428 +
.../jquery.plupload.queue.min.js | 1 +
.../css/jquery.ui.plupload.css | 371 +
.../css/jquery.ui.plupload.css.orig | 370 +
.../jquery.ui.plupload/img/loading.gif | Bin 0 -> 4023 bytes
.../jquery.ui.plupload/img/plupload.png | Bin 0 -> 6597 bytes
.../jquery.ui.plupload/jquery.ui.plupload.js | 1323 +
.../jquery.ui.plupload.min.js | 1 +
.../default/js/plugins/plupload/moxie.js | 10726 ++++++++
.../default/js/plugins/plupload/moxie.min.js | 15 +
.../js/plugins/plupload/plupload.dev.js | 2315 ++
.../js/plugins/plupload/plupload.full.min.js | 28 +
.../js/plugins/plupload/plupload.min.js | 13 +
.../default/js/plugins/selectize.clear.css | 387 +
.../default/js/plugins/selectize.dark.css | 385 +
.../default/js/plugins/selectize.min.js | 3 +
.../themes/default/js/plugins/tree.jquery.js | 18 +
.../themes/default/js/plugins/underscore.js | 1276 +
.../piwigo/themes/default/js/pngfix.js | 37 +
.../piwigo/themes/default/js/rating.js | 97 +
.../piwigo/themes/default/js/scripts.js | 155 +
.../piwigo/themes/default/js/switchbox.js | 23 +
.../themes/default/js/thumbnails.loader.js | 38 +
.../default/js/ui/i18n/jquery-ui-i18n.js | 1645 ++
.../js/ui/i18n/jquery.ui.datepicker-af.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-ar-DZ.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-ar.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-az.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-bg.js | 24 +
.../js/ui/i18n/jquery.ui.datepicker-bs.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-ca.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-cs.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-cy-GB.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-da.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-de.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-el.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-en-AU.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-en-GB.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-en-NZ.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-eo.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-es.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-et.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-eu.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-fa.js | 59 +
.../js/ui/i18n/jquery.ui.datepicker-fi.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-fo.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-fr-CH.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-fr.js | 25 +
.../js/ui/i18n/jquery.ui.datepicker-gl.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-he.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-hi.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-hr.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-hu.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-hy.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-id.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-is.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-it.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-ja.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-ka.js | 21 +
.../js/ui/i18n/jquery.ui.datepicker-kk.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-km.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-ko.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-lb.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-lt.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-lv.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-mk.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-ml.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-ms.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-nl.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-no.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-pl.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-pt-BR.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-pt.js | 22 +
.../js/ui/i18n/jquery.ui.datepicker-rm.js | 21 +
.../js/ui/i18n/jquery.ui.datepicker-ro.js | 26 +
.../js/ui/i18n/jquery.ui.datepicker-ru.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-sk.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-sl.js | 24 +
.../js/ui/i18n/jquery.ui.datepicker-sq.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-sr-SR.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-sr.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-sv.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-ta.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-th.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-tj.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-tr.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-uk.js | 24 +
.../js/ui/i18n/jquery.ui.datepicker-vi.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-zh-CN.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-zh-HK.js | 23 +
.../js/ui/i18n/jquery.ui.datepicker-zh-TW.js | 23 +
.../js/ui/i18n/jquery.ui.timepicker-af.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-am.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-bg.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-ca.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-cs.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-da.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-de.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-el.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-es.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-et.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-eu.js | 22 +
.../js/ui/i18n/jquery.ui.timepicker-fi.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-fr.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-gl.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-he.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-hr.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-hu.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-id.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-it.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-ja.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-ko.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-lt.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-nl.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-no.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-pl.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-pt-BR.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-pt.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-ro.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-ru.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-sk.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-sr-RS.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-sr-YU.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-sv.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-th.js | 18 +
.../js/ui/i18n/jquery.ui.timepicker-tr.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-uk.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-vi.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-zh-CN.js | 21 +
.../js/ui/i18n/jquery.ui.timepicker-zh-TW.js | 21 +
.../default/js/ui/jquery.ui.accordion.js | 570 +
.../default/js/ui/jquery.ui.autocomplete.js | 606 +
.../themes/default/js/ui/jquery.ui.button.js | 395 +
.../themes/default/js/ui/jquery.ui.core.js | 320 +
.../default/js/ui/jquery.ui.datepicker.js | 2038 ++
.../themes/default/js/ui/jquery.ui.dialog.js | 823 +
.../default/js/ui/jquery.ui.draggable.js | 958 +
.../default/js/ui/jquery.ui.droppable.js | 389 +
.../default/js/ui/jquery.ui.effect-blind.js | 82 +
.../default/js/ui/jquery.ui.effect-bounce.js | 113 +
.../default/js/ui/jquery.ui.effect-clip.js | 67 +
.../default/js/ui/jquery.ui.effect-drop.js | 65 +
.../default/js/ui/jquery.ui.effect-explode.js | 97 +
.../default/js/ui/jquery.ui.effect-fade.js | 30 +
.../default/js/ui/jquery.ui.effect-fold.js | 76 +
.../js/ui/jquery.ui.effect-highlight.js | 50 +
.../default/js/ui/jquery.ui.effect-pulsate.js | 63 +
.../default/js/ui/jquery.ui.effect-scale.js | 318 +
.../default/js/ui/jquery.ui.effect-shake.js | 74 +
.../default/js/ui/jquery.ui.effect-slide.js | 64 +
.../js/ui/jquery.ui.effect-transfer.js | 47 +
.../themes/default/js/ui/jquery.ui.effect.js | 1289 +
.../themes/default/js/ui/jquery.ui.menu.js | 627 +
.../themes/default/js/ui/jquery.ui.mouse.js | 169 +
.../default/js/ui/jquery.ui.position.js | 501 +
.../default/js/ui/jquery.ui.progressbar.js | 145 +
.../default/js/ui/jquery.ui.resizable.js | 978 +
.../default/js/ui/jquery.ui.selectable.js | 277 +
.../themes/default/js/ui/jquery.ui.slider.js | 676 +
.../default/js/ui/jquery.ui.sortable.js | 1289 +
.../themes/default/js/ui/jquery.ui.spinner.js | 497 +
.../themes/default/js/ui/jquery.ui.tabs.js | 849 +
.../js/ui/jquery.ui.timepicker-addon.js | 2197 ++
.../themes/default/js/ui/jquery.ui.tooltip.js | 402 +
.../themes/default/js/ui/jquery.ui.widget.js | 521 +
.../js/ui/minified/jquery.ui.accordion.min.js | 5 +
.../ui/minified/jquery.ui.autocomplete.min.js | 5 +
.../js/ui/minified/jquery.ui.button.min.js | 5 +
.../js/ui/minified/jquery.ui.core.min.js | 5 +
.../ui/minified/jquery.ui.datepicker.min.js | 6 +
.../js/ui/minified/jquery.ui.dialog.min.js | 5 +
.../js/ui/minified/jquery.ui.draggable.min.js | 5 +
.../js/ui/minified/jquery.ui.droppable.min.js | 5 +
.../ui/minified/jquery.ui.effect-blind.min.js | 5 +
.../minified/jquery.ui.effect-bounce.min.js | 5 +
.../ui/minified/jquery.ui.effect-clip.min.js | 5 +
.../ui/minified/jquery.ui.effect-drop.min.js | 5 +
.../minified/jquery.ui.effect-explode.min.js | 5 +
.../ui/minified/jquery.ui.effect-fade.min.js | 5 +
.../ui/minified/jquery.ui.effect-fold.min.js | 5 +
.../jquery.ui.effect-highlight.min.js | 5 +
.../minified/jquery.ui.effect-pulsate.min.js | 5 +
.../ui/minified/jquery.ui.effect-scale.min.js | 5 +
.../ui/minified/jquery.ui.effect-shake.min.js | 5 +
.../ui/minified/jquery.ui.effect-slide.min.js | 5 +
.../minified/jquery.ui.effect-transfer.min.js | 5 +
.../js/ui/minified/jquery.ui.effect.min.js | 5 +
.../js/ui/minified/jquery.ui.menu.min.js | 5 +
.../js/ui/minified/jquery.ui.mouse.min.js | 5 +
.../js/ui/minified/jquery.ui.position.min.js | 5 +
.../ui/minified/jquery.ui.progressbar.min.js | 5 +
.../js/ui/minified/jquery.ui.resizable.min.js | 5 +
.../ui/minified/jquery.ui.selectable.min.js | 5 +
.../js/ui/minified/jquery.ui.slider.min.js | 5 +
.../js/ui/minified/jquery.ui.sortable.min.js | 5 +
.../js/ui/minified/jquery.ui.spinner.min.js | 5 +
.../js/ui/minified/jquery.ui.tabs.min.js | 5 +
.../jquery.ui.timepicker-addon.min.js | 5 +
.../js/ui/minified/jquery.ui.tooltip.min.js | 5 +
.../js/ui/minified/jquery.ui.widget.min.js | 5 +
.../js/ui/theme/images/animated-overlay.gif | Bin 0 -> 1738 bytes
.../images/ui-bg_flat_0_aaaaaa_40x100.png | Bin 0 -> 180 bytes
.../images/ui-bg_flat_75_ffffff_40x100.png | Bin 0 -> 178 bytes
.../images/ui-bg_glass_55_fbf9ee_1x400.png | Bin 0 -> 120 bytes
.../images/ui-bg_glass_65_ffffff_1x400.png | Bin 0 -> 105 bytes
.../images/ui-bg_glass_75_dadada_1x400.png | Bin 0 -> 111 bytes
.../images/ui-bg_glass_75_e6e6e6_1x400.png | Bin 0 -> 110 bytes
.../images/ui-bg_glass_95_fef1ec_1x400.png | Bin 0 -> 119 bytes
.../ui-bg_highlight-soft_75_cccccc_1x100.png | Bin 0 -> 101 bytes
.../theme/images/ui-icons_222222_256x240.png | Bin 0 -> 4369 bytes
.../theme/images/ui-icons_2e83ff_256x240.png | Bin 0 -> 4369 bytes
.../theme/images/ui-icons_454545_256x240.png | Bin 0 -> 4369 bytes
.../theme/images/ui-icons_888888_256x240.png | Bin 0 -> 4369 bytes
.../theme/images/ui-icons_cd0a0a_256x240.png | Bin 0 -> 4369 bytes
.../js/ui/theme/jquery.ui.accordion.css | 38 +
.../default/js/ui/theme/jquery.ui.all.css | 12 +
.../js/ui/theme/jquery.ui.autocomplete.css | 16 +
.../default/js/ui/theme/jquery.ui.base.css | 25 +
.../default/js/ui/theme/jquery.ui.button.css | 114 +
.../default/js/ui/theme/jquery.ui.core.css | 93 +
.../js/ui/theme/jquery.ui.datepicker.css | 175 +
.../default/js/ui/theme/jquery.ui.dialog.css | 70 +
.../default/js/ui/theme/jquery.ui.menu.css | 79 +
.../js/ui/theme/jquery.ui.progressbar.css | 28 +
.../js/ui/theme/jquery.ui.resizable.css | 76 +
.../js/ui/theme/jquery.ui.selectable.css | 13 +
.../default/js/ui/theme/jquery.ui.slider.css | 73 +
.../default/js/ui/theme/jquery.ui.spinner.css | 65 +
.../default/js/ui/theme/jquery.ui.tabs.css | 51 +
.../default/js/ui/theme/jquery.ui.theme.css | 410 +
.../ui/theme/jquery.ui.timepicker-addon.css | 11 +
.../default/js/ui/theme/jquery.ui.tooltip.css | 21 +
.../piwigo/themes/default/local_head.tpl | 9 +
.../piwigo/themes/default/print.css | 16 +
.../piwigo/themes/default/s26/index.htm | 1 +
.../themes/default/s26/outline_005e89.png | Bin 0 -> 1935 bytes
.../themes/default/s26/outline_808060.png | Bin 0 -> 1935 bytes
.../themes/default/s26/outline_808080.png | Bin 0 -> 2555 bytes
.../themes/default/s26/outline_ff3363.png | Bin 0 -> 1935 bytes
.../themes/default/s26/outline_ff7700.png | Bin 0 -> 1935 bytes
.../themes/default/s26/outline_ffff80.png | Bin 0 -> 1935 bytes
.../themes/default/s26/outline_ffffff.png | Bin 0 -> 2230 bytes
.../piwigo/themes/default/template/about.tpl | 24 +
.../themes/default/template/comment_list.tpl | 81 +
.../themes/default/template/comments.tpl | 112 +
.../piwigo/themes/default/template/footer.tpl | 40 +
.../piwigo/themes/default/template/header.tpl | 91 +
.../default/template/help/quick_search.tpl | 306 +
.../default/template/identification.tpl | 66 +
.../default/template/include/autosize.inc.tpl | 9 +
.../default/template/include/colorbox.inc.tpl | 2 +
.../template/include/related_tags.inc.tpl | 12 +
.../template/include/search_filters.inc.tpl | 933 +
.../template/include/selected_tags.inc.tpl | 16 +
.../piwigo/themes/default/template/index.tpl | 239 +
.../themes/default/template/infos_errors.tpl | 19 +
.../themes/default/template/mail/index.php | 15 +
.../template/mail/screenshot-clear.png | Bin 0 -> 70946 bytes
.../default/template/mail/screenshot-dark.png | Bin 0 -> 72394 bytes
.../mail/text/html/cat_group_info.tpl | 10 +
.../template/mail/text/html/footer.tpl | 23 +
.../mail/text/html/global-mail-css.tpl | 103 +
.../template/mail/text/html/header.tpl | 29 +
.../default/template/mail/text/html/index.php | 15 +
.../mail/text/html/mail-css-clear.tpl | 71 +
.../template/mail/text/html/mail-css-dark.tpl | 85 +
.../mail/text/html/notification_admin.tpl | 9 +
.../mail/text/html/notification_by_mail.tpl | 56 +
.../default/template/mail/text/index.php | 15 +
.../mail/text/plain/cat_group_info.tpl | 8 +
.../template/mail/text/plain/footer.tpl | 7 +
.../template/mail/text/plain/header.tpl | 6 +
.../template/mail/text/plain/index.php | 15 +
.../mail/text/plain/notification_admin.tpl | 8 +
.../mail/text/plain/notification_by_mail.tpl | 41 +
.../default/template/mainpage_categories.tpl | 48 +
.../themes/default/template/menubar.tpl | 13 +
.../default/template/menubar_categories.tpl | 32 +
.../template/menubar_identification.tpl | 64 +
.../themes/default/template/menubar_links.tpl | 12 +
.../themes/default/template/menubar_menu.tpl | 18 +
.../template/menubar_related_categories.tpl | 28 +
.../default/template/menubar_specials.tpl | 8 +
.../themes/default/template/menubar_tags.tpl | 16 +
.../default/template/month_calendar.tpl | 81 +
.../default/template/navigation_bar.tpl | 28 +
.../piwigo/themes/default/template/nbm.tpl | 11 +
.../themes/default/template/no_photo_yet.tpl | 154 +
.../themes/default/template/notification.tpl | 29 +
.../themes/default/template/password.tpl | 79 +
.../themes/default/template/picture.tpl | 368 +
.../default/template/picture_content.tpl | 33 +
.../default/template/picture_nav_buttons.tpl | 121 +
.../themes/default/template/popuphelp.tpl | 25 +
.../themes/default/template/profile.tpl | 13 +
.../default/template/profile_content.tpl | 107 +
.../themes/default/template/redirect.tpl | 9 +
.../themes/default/template/register.tpl | 69 +
.../piwigo/themes/default/template/search.tpl | 150 +
.../themes/default/template/search_rules.tpl | 61 +
.../themes/default/template/slideshow.tpl | 24 +
.../piwigo/themes/default/template/tags.tpl | 57 +
.../themes/default/template/thumbnails.tpl | 64 +
.../piwigo/themes/default/theme.css | 1005 +
.../piwigo/themes/default/themeconf.inc.php | 9 +
.../default/vendor/fontello/LICENSE.txt | 48 +
.../themes/default/vendor/fontello/README.txt | 75 +
.../default/vendor/fontello/config.json | 412 +
.../default/vendor/fontello/css/animation.css | 85 +
.../fontello/css/gallery-icon-codes.css | 44 +
.../fontello/css/gallery-icon-embedded.css | 102 +
.../fontello/css/gallery-icon-ie7-codes.css | 43 +
.../vendor/fontello/css/gallery-icon-ie7.css | 54 +
.../vendor/fontello/css/gallery-icon.css | 99 +
.../themes/default/vendor/fontello/demo.html | 364 +
.../vendor/fontello/font/gallery-icon.eot | Bin 0 -> 17544 bytes
.../vendor/fontello/font/gallery-icon.svg | 94 +
.../vendor/fontello/font/gallery-icon.ttf | Bin 0 -> 17360 bytes
.../vendor/fontello/font/gallery-icon.woff | Bin 0 -> 10896 bytes
.../vendor/fontello/font/gallery-icon.woff2 | Bin 0 -> 9032 bytes
.../themes/default/watermarks/Owned_Stamp.png | Bin 0 -> 42282 bytes
.../themes/default/watermarks/Sample.png | Bin 0 -> 21395 bytes
.../default/watermarks/copyright-2023.png | Bin 0 -> 30749 bytes
.../default/watermarks/copyright-2024.png | Bin 0 -> 30726 bytes
.../themes/default/watermarks/copyright.png | Bin 0 -> 9424 bytes
Piwingo/piwigo-data/piwigo/themes/index.php | 15 +
.../fonts/OpenSans-VariableFont_wdth,wght.ttf | Bin 0 -> 529700 bytes
.../standard_pages/images/piwigo_logo.svg | 26 +
.../images/piwigo_logo_dark.svg | 16 +
.../themes/standard_pages/js/profile.js | 560 +
.../standard_pages/js/standard_pages.js | 133 +
.../themes/standard_pages/js/toaster.js | 32 +
.../themes/standard_pages/skins/cadmium.css | 341 +
.../themes/standard_pages/skins/cobalt.css | 341 +
.../standard_pages/skins/dark-cadmium.jpg | Bin 0 -> 25485 bytes
.../standard_pages/skins/dark-cobalt.jpg | Bin 0 -> 24304 bytes
.../standard_pages/skins/dark-default.jpg | Bin 0 -> 25115 bytes
.../standard_pages/skins/dark-fuchsia.jpg | Bin 0 -> 24424 bytes
.../standard_pages/skins/dark-green.jpg | Bin 0 -> 24341 bytes
.../themes/standard_pages/skins/dark-lime.jpg | Bin 0 -> 25011 bytes
.../standard_pages/skins/dark-purple.jpg | Bin 0 -> 23946 bytes
.../themes/standard_pages/skins/dark-red.jpg | Bin 0 -> 24663 bytes
.../standard_pages/skins/dark-sienna.jpg | Bin 0 -> 24386 bytes
.../standard_pages/skins/dark-silver.jpg | Bin 0 -> 24016 bytes
.../themes/standard_pages/skins/dark-teal.jpg | Bin 0 -> 24985 bytes
.../themes/standard_pages/skins/default.css | 337 +
.../themes/standard_pages/skins/fuchsia.css | 341 +
.../themes/standard_pages/skins/green.css | 343 +
.../standard_pages/skins/light-cadmium.jpg | Bin 0 -> 28350 bytes
.../standard_pages/skins/light-cobalt.jpg | Bin 0 -> 29816 bytes
.../standard_pages/skins/light-default.jpg | Bin 0 -> 28379 bytes
.../standard_pages/skins/light-fuchsia.jpg | Bin 0 -> 27904 bytes
.../standard_pages/skins/light-green.jpg | Bin 0 -> 29648 bytes
.../standard_pages/skins/light-lime.jpg | Bin 0 -> 27258 bytes
.../standard_pages/skins/light-purple.jpg | Bin 0 -> 29307 bytes
.../themes/standard_pages/skins/light-red.jpg | Bin 0 -> 31092 bytes
.../standard_pages/skins/light-sienna.jpg | Bin 0 -> 28312 bytes
.../standard_pages/skins/light-silver.jpg | Bin 0 -> 26250 bytes
.../standard_pages/skins/light-teal.jpg | Bin 0 -> 28769 bytes
.../themes/standard_pages/skins/lime.css | 341 +
.../themes/standard_pages/skins/purple.css | 343 +
.../themes/standard_pages/skins/red.css | 341 +
.../themes/standard_pages/skins/sienna.css | 341 +
.../themes/standard_pages/skins/silver.css | 341 +
.../themes/standard_pages/skins/teal.css | 343 +
.../themes/standard_pages/template/footer.tpl | 6 +
.../themes/standard_pages/template/header.tpl | 42 +
.../template/identification.tpl | 123 +
.../standard_pages/template/password.tpl | 181 +
.../standard_pages/template/profile.tpl | 495 +
.../standard_pages/template/register.tpl | 125 +
.../standard_pages/template/toaster.tpl | 59 +
.../piwigo/themes/standard_pages/theme.css | 859 +
.../themes/standard_pages/themeconf.inc.php | 28 +
.../piwigo-data/piwigo/tools/fill_history.pl | 336 +
.../piwigo/tools/github_issues.php | 55 +
Piwingo/piwigo-data/piwigo/tools/index.php | 15 +
.../language/translation_validated.inc.php | 653 +
Piwingo/piwigo-data/piwigo/tools/metadata.php | 118 +
.../piwigo-data/piwigo/tools/missing_keys.pl | 193 +
.../piwigo/tools/piwigo_addSimple.pl | 36 +
.../piwigo-data/piwigo/tools/piwigo_remote.pl | 434 +
.../piwigo-data/piwigo/tools/piwigo_upload.pl | 121 +
.../piwigo/tools/pwg_rel_create.sh | 142 +
.../piwigo-data/piwigo/tools/remote_sync.pl | 59 +
.../piwigo/tools/replace_version.pl | 39 +
.../piwigo-data/piwigo/tools/test_piwigo.php | 340 +
.../piwigo/tools/translation_analysis.php | 154 +
.../piwigo/tools/triggers_list.php | 1108 +
Piwingo/piwigo-data/piwigo/tools/ws.htm | 206 +
.../piwigo/tools/ws/jquery.json-viewer.css | 57 +
.../piwigo/tools/ws/jquery.json-viewer.js | 158 +
.../piwigo/tools/ws/piwigo-logo-minimal.svg | 66 +
Piwingo/piwigo-data/piwigo/tools/ws/ws.css | 633 +
Piwingo/piwigo-data/piwigo/tools/ws/ws.js | 540 +
Piwingo/piwigo-data/piwigo/upgrade.php | 577 +
Piwingo/piwigo-data/piwigo/upgrade_feed.php | 101 +
Piwingo/piwigo-data/piwigo/ws.php | 1714 ++
copyparty/.env | 2 +
copyparty/copyparty/copyparty.conf | 64 +
copyparty/docker-compose.yml | 32 +
copyparty/get_hashes | 1 +
gameyfin/.env | 12 +
gameyfin/docker-compose.yml | 18 +
gitea-runner/.runner | 14 +
gitea-runner/.runner.lock | 0
gitea-runner/README.md | 7 +
gitea-runner/runner | Bin 0 -> 19570848 bytes
gitea/.env | 7 +
gitea/docker-compose.yml | 25 +
hoodik/.env | 8 +
hoodik/docker-compose.yml | 13 +
immich/.env | 23 +
immich/docker-compose.yml | 77 +
jellyfin/.env | 5 +
jellyfin/docker-compose.yml | 26 +
navidrome/.env | 14 +
navidrome/docker-compose.yaml | 12 +
neoforge/cm | 13 +
neoforge/docker-compose.yml | 14 +
neoforge/mc/.neoforge-manifest.json | 1 +
neoforge/mc/.rcon-cli.env | 1 +
neoforge/mc/.rcon-cli.yaml | 1 +
neoforge/mc/.run-neoforge.env | 4 +
nextcloud/docker-compose.yml | 41 +
owncloud-docker-server/.env | 8 +
owncloud-docker-server/docker-compose.yml | 47 +
portainer/docker-compose.yml | 18 +
portal-runner-convert/docker-compose.yml | 6 +
rstack/.env | 21 +
rstack/docker-compose.yml | 167 +
seafile/.env | 9 +
seafile/docker-compose.yml | 44 +
synapse/config.yaml | 22 +
synapse/docker-compose.yml | 25 +
2840 files changed, 467153 insertions(+)
create mode 100644 Piwingo/.env
create mode 100644 Piwingo/compose.yaml
create mode 100644 Piwingo/piwigo-data/mysql/mariadb_upgrade_info
create mode 100644 Piwingo/piwigo-data/piwigo/.gitignore
create mode 100644 Piwingo/piwigo-data/piwigo/COPYING.txt
create mode 100644 Piwingo/piwigo-data/piwigo/LICENSE.txt
create mode 100644 Piwingo/piwigo-data/piwigo/README.md
create mode 100644 Piwingo/piwigo-data/piwigo/SECURITY.md
create mode 100644 Piwingo/piwigo-data/piwigo/about.php
create mode 100644 Piwingo/piwigo-data/piwigo/action.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/album.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/album_notification.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/albums.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/batch_manager.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/batch_manager_global.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/batch_manager_unit.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/cat_list.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/cat_modify.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/cat_options.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/cat_perm.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/comments.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/configuration.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/element_set_ranks.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/extend_for_templates.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/group_list.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/group_perm.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/help.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/history.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/include/add_core_tabs.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/include/albums_tab.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/include/batch_manager_filters.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/include/c13y_internal.class.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/include/check_integrity.class.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/include/configuration_sizes_process.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/include/configuration_watermark_process.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/include/functions.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/include/functions_history.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/include/functions_install.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/include/functions_metadata.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/include/functions_notification_by_mail.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/include/functions_permalinks.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/include/functions_plugins.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/include/functions_upgrade.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/include/functions_upload.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/include/image.class.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/include/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/include/languages.class.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/include/pclzip.lib.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/include/photos_add_direct_prepare.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/include/plugins.class.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/include/tabsheet.class.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/include/themes.class.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/include/updates.class.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/include/user_tabs.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/intro.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/languages.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/languages_installed.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/languages_new.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/maintenance.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/maintenance_actions.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/maintenance_env.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/maintenance_sys.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/menubar.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/notification_by_mail.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/permalinks.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/photo.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/photos_add.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/photos_add_applications.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/photos_add_direct.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/photos_add_ftp.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/picture_coi.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/picture_formats.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/picture_modify.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/plugin.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/plugins.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/plugins_installed.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/plugins_new.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/popuphelp.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/profile.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/rating.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/rating_user.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/site_manager.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/site_reader_local.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/site_update.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/stats.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/tags.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/theme.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/css/components/general.css
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/cat_move.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/category_children.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/category_delete.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/category_edit.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/category_elements.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/category_jump-to.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/category_permissions.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/category_representant_random.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/check.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/delete.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/edit_s.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/exit.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/help.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/home.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/infos.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/minus.gif
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/next.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/page_end.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/page_top.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/permissions.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/plus.gif
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/preferences.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/prev.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/remove_filter.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/remove_filter_hover.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/toggle_is_default_group.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/uncheck.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/validate_s.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/virt_category.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/warning.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/images/cancel.svg
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/images/cancelhover.svg
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/images/external_active.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/images/external_inactive.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/images/missing_screenshot.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/images/quickLocalSync.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/images/stripe-cat.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/images/transparent.gif
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/mail-css.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/theme.css
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/clear/themeconf.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/css/components/album_selector.css
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/css/components/general.css
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fontello/LICENSE.txt
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fontello/README.txt
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fontello/config.json
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fontello/css/animation.css
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fontello/css/fontello-codes.css
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fontello/css/fontello-embedded.css
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fontello/css/fontello-ie7-codes.css
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fontello/css/fontello-ie7.css
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fontello/css/fontello.css
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fontello/demo.html
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fontello/font/fontello.eot
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fontello/font/fontello.svg
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fontello/font/fontello.ttf
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fontello/font/fontello.woff
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fontello/font/fontello.woff2
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/README.md
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/bower.json
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/Bold/OpenSans-Bold.eot
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/Bold/OpenSans-Bold.svg
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/Bold/OpenSans-Bold.ttf
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/Bold/OpenSans-Bold.woff
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/Bold/OpenSans-Bold.woff2
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/BoldItalic/OpenSans-BoldItalic.eot
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/BoldItalic/OpenSans-BoldItalic.svg
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/BoldItalic/OpenSans-BoldItalic.ttf
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/BoldItalic/OpenSans-BoldItalic.woff
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/BoldItalic/OpenSans-BoldItalic.woff2
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/DESCRIPTION.en_us.html
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/ExtraBold/OpenSans-ExtraBold.eot
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/ExtraBold/OpenSans-ExtraBold.svg
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/ExtraBold/OpenSans-ExtraBold.ttf
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/ExtraBold/OpenSans-ExtraBold.woff
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/ExtraBold/OpenSans-ExtraBold.woff2
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/ExtraBoldItalic/OpenSans-ExtraBoldItalic.eot
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/ExtraBoldItalic/OpenSans-ExtraBoldItalic.svg
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/ExtraBoldItalic/OpenSans-ExtraBoldItalic.ttf
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/ExtraBoldItalic/OpenSans-ExtraBoldItalic.woff
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/ExtraBoldItalic/OpenSans-ExtraBoldItalic.woff2
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/Italic/OpenSans-Italic.eot
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/Italic/OpenSans-Italic.svg
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/Italic/OpenSans-Italic.ttf
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/Italic/OpenSans-Italic.woff
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/Italic/OpenSans-Italic.woff2
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/LICENSE.txt
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/Light/OpenSans-Light.eot
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/Light/OpenSans-Light.svg
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/Light/OpenSans-Light.ttf
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/Light/OpenSans-Light.woff
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/Light/OpenSans-Light.woff2
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/LightItalic/OpenSans-LightItalic.eot
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/LightItalic/OpenSans-LightItalic.svg
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/LightItalic/OpenSans-LightItalic.ttf
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/LightItalic/OpenSans-LightItalic.woff
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/LightItalic/OpenSans-LightItalic.woff2
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/METADATA.pb
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/Regular/OpenSans-Regular.eot
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/Regular/OpenSans-Regular.svg
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/Regular/OpenSans-Regular.ttf
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/Regular/OpenSans-Regular.woff
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/Regular/OpenSans-Regular.woff2
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/Semibold/OpenSans-SemiBold2.eot
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/Semibold/OpenSans-Semibold.eot
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/Semibold/OpenSans-Semibold.svg
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/Semibold/OpenSans-Semibold.ttf
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/Semibold/OpenSans-Semibold.woff
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/Semibold/OpenSans-Semibold.woff2
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/SemiboldItalic/OpenSans-SemiboldItalic.eot
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/SemiboldItalic/OpenSans-SemiboldItalic.svg
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/SemiboldItalic/OpenSans-SemiboldItalic.ttf
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/SemiboldItalic/OpenSans-SemiboldItalic.woff
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/fonts/SemiboldItalic/OpenSans-SemiboldItalic.woff2
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/index.html
create mode 100755 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/open-sans.css
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/open-sans.expanded.css
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/open-sans.less
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/open-sans.prefixed.css
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/open-sans.scss
create mode 100755 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/sass/_Bold.scss
create mode 100755 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/sass/_BoldItalic.scss
create mode 100755 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/sass/_ExtraBold.scss
create mode 100755 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/sass/_ExtraBoldItalic.scss
create mode 100755 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/sass/_Italic.scss
create mode 100755 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/sass/_Light.scss
create mode 100755 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/sass/_LightItalic.scss
create mode 100755 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/sass/_Regular.scss
create mode 100755 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/sass/_Semibold.scss
create mode 100755 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/sass/_SemiboldItalic.scss
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/sass/_mixins.scss
create mode 100755 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/sass/_variables.scss
create mode 100755 Piwingo/piwigo-data/piwigo/admin/themes/default/fonts/open-sans/sass/open-sans.scss
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/icon/cat_move.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/icon/category_children.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/icon/category_delete.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/icon/category_edit.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/icon/category_elements.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/icon/category_jump-to.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/icon/category_permissions.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/icon/category_representant_random.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/icon/check.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/icon/delete.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/icon/edit_s.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/icon/errors.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/icon/exit.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/icon/fcbkcomplete_close.gif
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/icon/help-min.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/icon/help.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/icon/home.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/icon/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/icon/infos.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/icon/minus.gif
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/icon/note.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/icon/page_end.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/icon/page_top.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/icon/permissions.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/icon/plus.gif
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/icon/preferences.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/icon/toggle_is_default_group.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/icon/uncheck.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/icon/validate_s.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/icon/virt_category.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/icon/warning.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/icon/warnings.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/images/ajax-loader-bar.gif
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/images/ajax-loader.gif
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/images/cancel.svg
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/images/cancelhover.svg
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/images/certification/Certification.svg
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/images/certification/CertificationBlue.svg
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/images/certification/CertificationGhost.svg
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/images/certification/CertificationOrange.svg
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/images/certification/CertificationWarning.svg
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/images/pbar-ani.gif
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/images/piwigo-grey.svg
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/images/piwigo-orange.svg
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/images/piwigo_app_banner.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/images/promote-newsletter.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/js/LocalStorageCache.js
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/js/addAlbum.js
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/js/album_selector.js
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/js/albums.js
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/js/batchManagerFilter.js
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/js/batchManagerGlobal.js
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/js/batchManagerUnit.js
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/js/cat_list.js
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/js/cat_modify.js
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/js/cat_search.js
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/js/comments.js
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/js/common.js
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/js/datepicker.js
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/js/doubleSlider.js
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/js/group_list.js
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/js/history.js
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/js/intro_tooltips.js
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/js/jquery.geoip.js
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/js/maintenance.js
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/js/maintenance_env.js
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/js/maintenance_sys.js
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/js/photos_add_direct.js
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/js/picture_formats.js
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/js/picture_modify.js
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/js/plugins_installated.js
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/js/plugins_new.js
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/js/stats.js
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/js/tags.js
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/js/user_activity.js
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/js/user_list.js
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/print.css
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/admin.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/album_notification.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/albums.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/batch_manager_global.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/batch_manager_unit.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/cat_list.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/cat_modify.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/cat_options.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/cat_perm.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/check_integrity.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/comments.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/configuration_comments.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/configuration_default.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/configuration_display.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/configuration_main.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/configuration_search.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/configuration_sizes.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/configuration_watermark.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/double_select.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/element_set_ranks.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/extend_for_templates.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/footer.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/group_list.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/group_perm.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/header.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/help.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/history.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/include/add_album.inc.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/include/album_selector.inc.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/include/autosize.inc.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/include/batch_manager_filter.inc.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/include/colorbox.inc.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/include/datepicker.inc.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/include/install.inc.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/install.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/intro.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/languages_installed.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/languages_new.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/maintenance_actions.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/maintenance_env.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/maintenance_sys.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/menubar.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/navigation_bar.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/notification_by_mail.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/permalinks.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/photos_add_applications.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/photos_add_direct.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/photos_add_ftp.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/picture_coi.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/picture_formats.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/picture_modify.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/plugins_installed.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/plugins_new.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/popuphelp.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/rating.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/rating_user.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/site_manager.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/site_update.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/stats.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/tabsheet.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/tags.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/themes_installed.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/themes_new.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/themes_standard_pages.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/updates_ext.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/updates_pwg.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/upgrade.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/user_activity.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/user_list.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/template/user_perm.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/theme.css
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/default/themeconf.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/roma/css/components/general.css
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/roma/icon/home.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/roma/icon/next.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/roma/icon/prev.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/roma/images/active_tab.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/roma/images/active_tab2.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/roma/images/active_tab3.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/roma/images/cancel.svg
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/roma/images/cancelhover.svg
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/roma/images/certification/CertificationWarningDM.svg
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/roma/images/external_active.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/roma/images/external_inactive.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/roma/images/fillet.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/roma/images/header_msgs-bg.gif
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/roma/images/inactive_tab.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/roma/images/inactive_tab2.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/roma/images/inactive_tab3.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/roma/images/menuBoxBottom_new.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/roma/images/menuBoxTop_new.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/roma/images/menubar-detail.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/roma/images/menubar-top.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/roma/images/missing_screenshot.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/roma/images/quickLocalSync_hover.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/roma/images/quickLocalSync_inactiv.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/roma/images/stripe-cat.png
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/roma/images/transparent.gif
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/roma/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/roma/mail-css.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/roma/theme.css
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes/roma/themeconf.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes_installed.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes_new.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/themes_standard_pages.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/updates.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/updates_ext.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/updates_pwg.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/user_activity.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/user_list.php
create mode 100644 Piwingo/piwigo-data/piwigo/admin/user_perm.php
create mode 100644 Piwingo/piwigo-data/piwigo/comments.php
create mode 100644 Piwingo/piwigo-data/piwigo/doc/COPYING
create mode 100644 Piwingo/piwigo-data/piwigo/doc/README_ca.txt
create mode 100644 Piwingo/piwigo-data/piwigo/doc/README_en.txt
create mode 100644 Piwingo/piwigo-data/piwigo/doc/README_fr.txt
create mode 100644 Piwingo/piwigo-data/piwigo/doc/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/docs/CONTRIBUTING.md
create mode 100644 Piwingo/piwigo-data/piwigo/docs/HowToFork.png
create mode 100644 Piwingo/piwigo-data/piwigo/docs/HowToPullRequest.png
create mode 100644 Piwingo/piwigo-data/piwigo/docs/Issue.PNG
create mode 100644 Piwingo/piwigo-data/piwigo/feed.php
create mode 100644 Piwingo/piwigo-data/piwigo/galleries/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/i.php
create mode 100644 Piwingo/piwigo-data/piwigo/identification.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/Logger.class.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/base32.class.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/block.class.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/cache.class.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/calendar_base.class.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/calendar_monthly.class.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/calendar_weekly.class.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/category_cats.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/category_default.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/common.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/config_default.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/constants.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/dblayer/functions_mysql.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/dblayer/functions_mysqli.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/derivative.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/derivative_params.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/derivative_std_params.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/emogrifier.class.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/feedcreator.class.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/filter.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/functions.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/functions_calendar.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/functions_category.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/functions_comment.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/functions_cookie.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/functions_filter.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/functions_html.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/functions_mail.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/functions_metadata.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/functions_notification.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/functions_picture.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/functions_plugins.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/functions_rate.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/functions_search.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/functions_session.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/functions_tag.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/functions_url.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/functions_user.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/inflectors/en.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/inflectors/fr.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/jshrink.class.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/mdetect.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/menubar.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/minify/LICENSE
create mode 100644 Piwingo/piwigo-data/piwigo/include/minify/data/js/keywords_after.txt
create mode 100644 Piwingo/piwigo-data/piwigo/include/minify/data/js/keywords_before.txt
create mode 100644 Piwingo/piwigo-data/piwigo/include/minify/data/js/keywords_reserved.txt
create mode 100644 Piwingo/piwigo-data/piwigo/include/minify/data/js/operators.txt
create mode 100644 Piwingo/piwigo-data/piwigo/include/minify/data/js/operators_after.txt
create mode 100644 Piwingo/piwigo-data/piwigo/include/minify/data/js/operators_before.txt
create mode 100644 Piwingo/piwigo-data/piwigo/include/minify/path-converter/LICENSE
create mode 100644 Piwingo/piwigo-data/piwigo/include/minify/path-converter/src/Converter.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/minify/path-converter/src/ConverterInterface.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/minify/path-converter/src/NoConverter.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/minify/src/CSS.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/minify/src/Exception.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/minify/src/Exceptions/BasicException.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/minify/src/Exceptions/FileImportException.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/minify/src/Exceptions/IOException.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/minify/src/Exceptions/PatternMatchException.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/minify/src/JS.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/minify/src/Minify.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/no_photo_yet.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/page_header.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/page_tail.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/passwordhash.class.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/php_compat/gzopen.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/php_compat/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/php_compat/str_starts_with.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/phpmailer/DSNConfigurator.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/phpmailer/Exception.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/phpmailer/OAuth.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/phpmailer/OAuthTokenProvider.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/phpmailer/PHPMailer.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/phpmailer/POP3.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/phpmailer/SMTP.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/phpqrcode.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/picture_comment.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/picture_metadata.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/picture_rate.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/pwgsession.class.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/pwgsession_php7.class.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/search_filters.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/section_init.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/selected_tags.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/CHANGELOG.md
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/LICENSE
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/README.md
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/SECURITY.md
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/libs/Smarty.class.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/BlockHandler/Base.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/BlockHandler/BlockHandlerInterface.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/BlockHandler/BlockPluginWrapper.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/BlockHandler/TextFormat.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Cacheresource/Base.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Cacheresource/Custom.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Cacheresource/File.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Cacheresource/KeyValueStore.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Base.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/BlockCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/CompilerInterface.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/DefaultHandlerBlockCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/DefaultHandlerFunctionCallCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/FunctionCallCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Modifier/BCPluginWrapper.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Modifier/Base.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Modifier/CatModifierCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Modifier/CountCharactersModifierCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Modifier/CountParagraphsModifierCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Modifier/CountSentencesModifierCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Modifier/CountWordsModifierCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Modifier/DefaultModifierCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Modifier/EmptyModifierCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Modifier/EscapeModifierCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Modifier/FromCharsetModifierCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Modifier/IndentModifierCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Modifier/IsArrayModifierCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Modifier/IssetModifierCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Modifier/JsonEncodeModifierCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Modifier/LowerModifierCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Modifier/ModifierCompilerInterface.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Modifier/Nl2brModifierCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Modifier/NoPrintModifierCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Modifier/RawModifierCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Modifier/RoundModifierCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Modifier/StrRepeatModifierCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Modifier/StringFormatModifierCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Modifier/StripModifierCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Modifier/StripTagsModifierCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Modifier/StrlenModifierCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Modifier/SubstrModifierCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Modifier/ToCharsetModifierCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Modifier/UnescapeModifierCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Modifier/UpperModifierCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Modifier/WordWrapModifierCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/ModifierCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/ObjectMethodBlockCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/ObjectMethodCallCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/PrintExpressionCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/SpecialVariableCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/Append.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/Assign.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/BCPluginWrapper.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/Block.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/BlockClose.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/BreakTag.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/Call.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/Capture.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/CaptureClose.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/ConfigLoad.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/ContinueTag.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/Debug.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/ElseIfTag.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/ElseTag.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/EvalTag.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/ExtendsTag.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/ForClose.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/ForElse.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/ForTag.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/ForeachClose.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/ForeachElse.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/ForeachSection.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/ForeachTag.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/FunctionClose.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/FunctionTag.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/IfClose.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/IfTag.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/IncludeTag.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/Inheritance.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/Ldelim.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/Nocache.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/NocacheClose.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/Rdelim.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/Section.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/SectionClose.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/SectionElse.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/Setfilter.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/SetfilterClose.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/WhileClose.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compile/Tag/WhileTag.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compiler/BaseCompiler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compiler/CodeFrame.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compiler/Configfile.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Compiler/Template.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/CompilerException.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Data.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Debug.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/ErrorHandler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Exception.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Extension/BCPluginsAdapter.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Extension/Base.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Extension/CallbackWrapper.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Extension/CoreExtension.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Extension/DefaultExtension.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Extension/ExtensionInterface.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Filter/FilterInterface.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Filter/FilterPluginWrapper.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Filter/Output/TrimWhitespace.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/FunctionHandler/BCPluginWrapper.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/FunctionHandler/Base.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/FunctionHandler/Count.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/FunctionHandler/Counter.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/FunctionHandler/Cycle.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/FunctionHandler/Fetch.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/FunctionHandler/FunctionHandlerInterface.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/FunctionHandler/HtmlBase.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/FunctionHandler/HtmlCheckboxes.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/FunctionHandler/HtmlImage.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/FunctionHandler/HtmlOptions.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/FunctionHandler/HtmlRadios.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/FunctionHandler/HtmlSelectDate.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/FunctionHandler/HtmlSelectTime.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/FunctionHandler/HtmlTable.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/FunctionHandler/Mailto.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/FunctionHandler/Math.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Lexer/ConfigfileLexer.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Lexer/ConfigfileLexer.plex
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Lexer/TemplateLexer.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Lexer/TemplateLexer.plex
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/ParseTree/Base.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/ParseTree/Code.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/ParseTree/Dq.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/ParseTree/DqContent.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/ParseTree/Tag.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/ParseTree/Template.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/ParseTree/Text.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Parser/ConfigfileParser.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Parser/ConfigfileParser.y
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Parser/TemplateParser.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Parser/TemplateParser.y
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Resource/BasePlugin.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Resource/CustomPlugin.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Resource/ExtendsPlugin.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Resource/FilePlugin.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Resource/RecompiledPlugin.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Resource/StreamPlugin.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Resource/StringEval.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Resource/StringPlugin.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Runtime/Block.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Runtime/CaptureRuntime.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Runtime/DefaultPluginHandlerRuntime.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Runtime/ForeachRuntime.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Runtime/InheritanceRuntime.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Runtime/TplFunctionRuntime.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Security.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Smarty.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Template.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Template/Cached.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Template/Compiled.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Template/Config.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Template/GeneratedPhpFile.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Template/Source.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/TemplateBase.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/TestInstall.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/UndefinedVariable.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/Variable.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/debug.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/include/smarty/src/functions.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/template.class.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/totp.class.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/user.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/ws_core.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/ws_functions.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/ws_functions/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/ws_functions/pwg.categories.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/ws_functions/pwg.comments.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/ws_functions/pwg.extensions.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/ws_functions/pwg.groups.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/ws_functions/pwg.images.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/ws_functions/pwg.permissions.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/ws_functions/pwg.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/ws_functions/pwg.tags.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/ws_functions/pwg.users.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/ws_init.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/ws_protocols/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/ws_protocols/json_encoder.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/ws_protocols/php_encoder.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/ws_protocols/rest_encoder.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/ws_protocols/rest_handler.php
create mode 100644 Piwingo/piwigo-data/piwigo/include/ws_protocols/xmlrpc_encoder.php
create mode 100644 Piwingo/piwigo-data/piwigo/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/install.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/config.sql
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/100-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/101-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/102-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/103-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/104-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/105-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/106-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/107-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/108-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/109-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/110-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/111-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/112-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/113-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/114-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/115-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/116-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/117-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/118-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/119-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/120-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/121-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/122-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/123-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/124-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/125-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/126-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/127-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/128-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/129-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/130-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/131-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/132-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/133-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/134-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/135-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/136-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/137-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/138-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/139-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/140-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/141-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/142-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/143-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/144-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/145-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/146-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/147-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/148-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/149-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/150-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/151-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/152-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/153-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/154-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/155-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/156-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/157-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/158-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/159-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/160-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/161-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/162-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/163-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/164-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/165-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/166-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/167-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/168-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/169-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/170-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/171-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/172-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/173-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/174-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/175-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/176-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/177-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/178-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/179-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/180-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/181-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/61-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/62-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/63-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/64-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/65-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/66-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/67-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/68-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/69-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/70-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/71-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/72-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/73-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/74-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/75-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/76-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/77-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/78-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/79-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/80-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/81-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/82-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/83-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/84-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/85-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/86-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/87-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/88-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/89-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/90-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/91-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/92-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/93-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/94-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/95-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/96-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/97-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/98-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/99-database.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/db/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/hosting.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/obsolete.list
create mode 100644 Piwingo/piwigo-data/piwigo/install/obsolete_extensions.list
create mode 100644 Piwingo/piwigo-data/piwigo/install/php5_apache_configuration.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/piwigo_structure-mysql.sql
create mode 100644 Piwingo/piwigo-data/piwigo/install/upgrade_1.3.0.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/upgrade_1.3.1.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/upgrade_1.4.0.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/upgrade_1.5.0.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/upgrade_1.6.0.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/upgrade_1.6.2.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/upgrade_1.7.0.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/upgrade_11.0.0.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/upgrade_12.0.0.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/upgrade_13.0.0.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/upgrade_14.0.0.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/upgrade_15.0.0.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/upgrade_2.0.0.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/upgrade_2.1.0.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/upgrade_2.10.0.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/upgrade_2.2.0.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/upgrade_2.3.0.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/upgrade_2.4.0.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/upgrade_2.5.0.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/upgrade_2.6.0.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/upgrade_2.7.0.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/upgrade_2.8.0.php
create mode 100644 Piwingo/piwigo-data/piwigo/install/upgrade_2.9.0.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/af_ZA/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/af_ZA/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/af_ZA/af_ZA.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/af_ZA/common.lang.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/af_ZA/help/cat_modify.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/af_ZA/help/cat_move.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/af_ZA/help/permalinks.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/af_ZA/help/search.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/af_ZA/help/synchronize.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/af_ZA/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/af_ZA/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/af_ZA/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/af_ZA/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/af_ZA/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_EG/ar_EG.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_EG/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_EG/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_EG/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_EG/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_MA/ar_MA.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_MA/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_MA/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_MA/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_SA/Translator.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_SA/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_SA/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_SA/ar_SA.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_SA/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_SA/help/cat_modify.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_SA/help/cat_move.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_SA/help/cat_options.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_SA/help/cat_perm.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_SA/help/configuration.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_SA/help/extend_for_templates.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_SA/help/group_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_SA/help/help_add_photos.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_SA/help/help_groups.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_SA/help/help_misc.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_SA/help/help_permissions.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_SA/help/help_virtual_links.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_SA/help/history.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_SA/help/maintenance.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_SA/help/notification_by_mail.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_SA/help/permalinks.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_SA/help/photos_add_ftp.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_SA/help/search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_SA/help/synchronize.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_SA/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_SA/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_SA/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_SA/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/ar_SA/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/az_AZ/az_AZ.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/az_AZ/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/az_AZ/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/bg_BG/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/bg_BG/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/bg_BG/bg_BG.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/bg_BG/common.lang.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/bg_BG/help/cat_modify.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/bg_BG/help/cat_move.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/bg_BG/help/cat_options.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/bg_BG/help/cat_perm.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/bg_BG/help/group_list.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/bg_BG/help/help_add_photos.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/bg_BG/help/help_groups.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/bg_BG/help/help_misc.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/bg_BG/help/permalinks.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/bg_BG/help/search.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/bg_BG/help/synchronize.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/bg_BG/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/bg_BG/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/bg_BG/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/bg_BG/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/bg_BG/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/bn_IN/bn_IN.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/bn_IN/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/bn_IN/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/br_FR/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/br_FR/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/br_FR/br_FR.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/br_FR/common.lang.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/br_FR/help/help_misc.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/br_FR/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/br_FR/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/br_FR/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ca_ES/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ca_ES/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ca_ES/ca_ES.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/ca_ES/common.lang.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/ca_ES/help/cat_modify.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/ca_ES/help/cat_move.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/ca_ES/help/cat_options.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/ca_ES/help/cat_perm.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/ca_ES/help/configuration.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/ca_ES/help/extend_for_templates.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/ca_ES/help/group_list.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/ca_ES/help/help_add_photos.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/ca_ES/help/help_groups.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/ca_ES/help/help_misc.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/ca_ES/help/help_permissions.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/ca_ES/help/help_virtual_links.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/ca_ES/help/history.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/ca_ES/help/maintenance.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/ca_ES/help/notification_by_mail.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/ca_ES/help/permalinks.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/ca_ES/help/photos_add_ftp.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/ca_ES/help/quick_search.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/ca_ES/help/search.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/ca_ES/help/synchronize.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/ca_ES/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ca_ES/help_quick_search.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ca_ES/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ca_ES/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/ca_ES/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ca_ES/whats_new_15.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ca_ES/whats_new_16.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/cs_CZ/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/cs_CZ/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/cs_CZ/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/cs_CZ/cs_CZ.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/cs_CZ/help/cat_modify.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/cs_CZ/help/cat_move.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/cs_CZ/help/cat_options.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/cs_CZ/help/cat_perm.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/cs_CZ/help/configuration.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/cs_CZ/help/extend_for_templates.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/cs_CZ/help/group_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/cs_CZ/help/help_add_photos.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/cs_CZ/help/help_groups.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/cs_CZ/help/help_misc.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/cs_CZ/help/help_permissions.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/cs_CZ/help/help_virtual_links.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/cs_CZ/help/history.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/cs_CZ/help/index.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/cs_CZ/help/maintenance.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/cs_CZ/help/notification_by_mail.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/cs_CZ/help/permalinks.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/cs_CZ/help/photos_add_ftp.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/cs_CZ/help/quick_search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/cs_CZ/help/search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/cs_CZ/help/synchronize.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/cs_CZ/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/cs_CZ/help_quick_search.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/cs_CZ/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/cs_CZ/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/cs_CZ/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/cs_CZ/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/cs_CZ/whats_new_15.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/cs_CZ/whats_new_16.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/da_DK/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/da_DK/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/da_DK/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/da_DK/da_DK.jpg
create mode 100755 Piwingo/piwigo-data/piwigo/language/da_DK/help/cat_modify.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/da_DK/help/cat_move.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/da_DK/help/cat_options.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/da_DK/help/cat_perm.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/da_DK/help/configuration.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/da_DK/help/extend_for_templates.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/da_DK/help/group_list.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/da_DK/help/help_add_photos.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/da_DK/help/help_groups.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/da_DK/help/help_misc.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/da_DK/help/help_permissions.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/da_DK/help/help_virtual_links.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/da_DK/help/history.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/da_DK/help/maintenance.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/da_DK/help/notification_by_mail.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/da_DK/help/permalinks.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/da_DK/help/photos_add_ftp.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/da_DK/help/quick_search.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/da_DK/help/search.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/da_DK/help/synchronize.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/da_DK/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/da_DK/help_quick_search.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/da_DK/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/da_DK/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/da_DK/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/da_DK/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/da_DK/whats_new_15.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/da_DK/whats_new_16.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/de_DE/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/de_DE/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/de_DE/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/de_DE/de_DE.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/de_DE/help/cat_modify.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/de_DE/help/cat_move.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/de_DE/help/cat_options.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/de_DE/help/cat_perm.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/de_DE/help/configuration.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/de_DE/help/extend_for_templates.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/de_DE/help/group_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/de_DE/help/help_add_photos.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/de_DE/help/help_groups.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/de_DE/help/help_misc.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/de_DE/help/help_permissions.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/de_DE/help/help_virtual_links.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/de_DE/help/history.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/de_DE/help/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/de_DE/help/maintenance.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/de_DE/help/notification_by_mail.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/de_DE/help/permalinks.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/de_DE/help/photos_add_ftp.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/de_DE/help/quick_search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/de_DE/help/search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/de_DE/help/synchronize.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/de_DE/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/de_DE/help_quick_search.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/de_DE/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/de_DE/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/de_DE/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/de_DE/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/de_DE/whats_new_15.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/de_DE/whats_new_16.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/dv_MV/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/dv_MV/dv_MV.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/dv_MV/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/dv_MV/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/el_GR/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/el_GR/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/el_GR/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/el_GR/el_GR.jpg
create mode 100755 Piwingo/piwigo-data/piwigo/language/el_GR/help/cat_modify.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/el_GR/help/cat_move.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/el_GR/help/cat_options.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/el_GR/help/cat_perm.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/el_GR/help/configuration.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/el_GR/help/extend_for_templates.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/el_GR/help/group_list.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/el_GR/help/help_add_photos.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/el_GR/help/help_groups.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/el_GR/help/help_misc.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/el_GR/help/help_permissions.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/el_GR/help/help_virtual_links.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/el_GR/help/history.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/el_GR/help/maintenance.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/el_GR/help/notification_by_mail.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/el_GR/help/permalinks.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/el_GR/help/photos_add_ftp.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/el_GR/help/quick_search.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/el_GR/help/search.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/el_GR/help/synchronize.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/el_GR/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/el_GR/help_quick_search.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/el_GR/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/el_GR/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/el_GR/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/el_GR/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/el_GR/whats_new_15.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/el_GR/whats_new_16.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_GB/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_GB/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_GB/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_GB/en_GB.jpg
create mode 100755 Piwingo/piwigo-data/piwigo/language/en_GB/help/quick_search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_GB/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_GB/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_GB/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_GB/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/en_UK.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/help/cat_modify.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/help/cat_move.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/help/cat_options.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/help/cat_perm.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/help/configuration.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/help/extend_for_templates.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/help/group_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/help/help_add_photos.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/help/help_groups.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/help/help_misc.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/help/help_permissions.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/help/help_virtual_links.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/help/history.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/help/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/help/maintenance.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/help/notification_by_mail.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/help/permalinks.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/help/photos_add_ftp.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/help/quick_search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/help/search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/help/synchronize.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/help_quick_search.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/whats_new_15.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_UK/whats_new_16.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_US/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_US/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_US/en_US.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_US/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/en_US/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/eo_EO/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/eo_EO/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/eo_EO/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/eo_EO/eo_EO.jpg
create mode 100755 Piwingo/piwigo-data/piwigo/language/eo_EO/help/cat_modify.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/eo_EO/help/cat_move.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/eo_EO/help/cat_options.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/eo_EO/help/cat_perm.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/eo_EO/help/group_list.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/eo_EO/help/help_groups.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/eo_EO/help/help_misc.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/eo_EO/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/eo_EO/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/eo_EO/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/eo_EO/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_AR/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_AR/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_AR/es_AR.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_AR/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_AR/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_ES/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_ES/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_ES/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_ES/es_ES.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_ES/help/cat_modify.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_ES/help/cat_move.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_ES/help/cat_options.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_ES/help/cat_perm.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_ES/help/configuration.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_ES/help/extend_for_templates.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_ES/help/group_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_ES/help/help_add_photos.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_ES/help/help_groups.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_ES/help/help_misc.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_ES/help/help_permissions.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_ES/help/help_virtual_links.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_ES/help/history.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_ES/help/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_ES/help/maintenance.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_ES/help/notification_by_mail.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_ES/help/permalinks.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_ES/help/photos_add_ftp.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/es_ES/help/quick_search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_ES/help/search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_ES/help/synchronize.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_ES/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_ES/help_quick_search.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_ES/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_ES/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_ES/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_ES/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_ES/whats_new_15.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_ES/whats_new_16.lang.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/es_MX/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_MX/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_MX/es_MX.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_MX/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/es_MX/iso.txt
create mode 100755 Piwingo/piwigo-data/piwigo/language/es_MX/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/et_EE/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/et_EE/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/et_EE/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/et_EE/et_EE.jpg
create mode 100755 Piwingo/piwigo-data/piwigo/language/et_EE/help/cat_modify.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/et_EE/help/cat_move.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/et_EE/help/cat_options.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/et_EE/help/cat_perm.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/et_EE/help/configuration.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/et_EE/help/group_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/et_EE/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/et_EE/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/et_EE/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/et_EE/whats_new_15.lang.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/eu_ES/about.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/eu_ES/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/eu_ES/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/eu_ES/eu_ES.jpg
create mode 100755 Piwingo/piwigo-data/piwigo/language/eu_ES/help/cat_modify.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/eu_ES/help/cat_move.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/eu_ES/help/cat_options.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/eu_ES/help/cat_perm.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/eu_ES/help/configuration.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/eu_ES/help/extend_for_templates.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/eu_ES/help/group_list.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/eu_ES/help/help_add_photos.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/eu_ES/help/help_groups.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/eu_ES/help/help_misc.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/eu_ES/help/help_permissions.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/eu_ES/help/help_virtual_links.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/eu_ES/help/history.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/eu_ES/help/maintenance.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/eu_ES/help/notification_by_mail.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/eu_ES/help/permalinks.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/eu_ES/help/photos_add_ftp.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/eu_ES/help/quick_search.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/eu_ES/help/search.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/eu_ES/help/synchronize.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/eu_ES/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/eu_ES/help_quick_search.lang.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/eu_ES/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/eu_ES/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/eu_ES/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/eu_ES/whats_new_15.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/fa_IR/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fa_IR/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/fa_IR/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/fa_IR/fa_IR.jpg
create mode 100755 Piwingo/piwigo-data/piwigo/language/fa_IR/help/cat_modify.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/fa_IR/help/cat_move.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/fa_IR/help/cat_options.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/fa_IR/help/help_add_photos.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/fa_IR/help/help_groups.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/fa_IR/help/help_misc.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fa_IR/help/index.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/fa_IR/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fa_IR/help_quick_search.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/fa_IR/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/fa_IR/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/fa_IR/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/fa_IR/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/fa_IR/whats_new_15.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/fi_FI/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fi_FI/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/fi_FI/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/fi_FI/fi_FI.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/fi_FI/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/fi_FI/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/fi_FI/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/fi_FI/whats_new_15.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_CA/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_CA/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_CA/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_CA/fr_CA.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_CA/help/cat_modify.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_CA/help/cat_move.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_CA/help/cat_options.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_CA/help/cat_perm.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_CA/help/configuration.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_CA/help/extend_for_templates.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_CA/help/group_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_CA/help/help_add_photos.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_CA/help/help_groups.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_CA/help/help_misc.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_CA/help/help_permissions.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_CA/help/help_virtual_links.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_CA/help/history.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_CA/help/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_CA/help/maintenance.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_CA/help/notification_by_mail.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_CA/help/permalinks.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_CA/help/photos_add_ftp.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/fr_CA/help/quick_search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_CA/help/search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_CA/help/synchronize.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_CA/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_CA/help_quick_search.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_CA/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_CA/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_CA/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_CA/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_FR/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_FR/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_FR/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_FR/fr_FR.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_FR/help/cat_modify.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_FR/help/cat_move.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_FR/help/cat_options.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_FR/help/cat_perm.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_FR/help/configuration.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_FR/help/extend_for_templates.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_FR/help/group_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_FR/help/help_add_photos.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_FR/help/help_groups.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_FR/help/help_misc.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_FR/help/help_permissions.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_FR/help/help_virtual_links.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_FR/help/history.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_FR/help/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_FR/help/maintenance.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_FR/help/notification_by_mail.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_FR/help/permalinks.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_FR/help/photos_add_ftp.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/fr_FR/help/quick_search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_FR/help/search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_FR/help/synchronize.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_FR/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_FR/help_quick_search.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_FR/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_FR/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_FR/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_FR/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_FR/whats_new_15.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/fr_FR/whats_new_16.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ga_IE/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ga_IE/ga_IE.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/ga_IE/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/gl_ES/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/gl_ES/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/gl_ES/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/gl_ES/gl_ES.jpg
create mode 100755 Piwingo/piwigo-data/piwigo/language/gl_ES/help/cat_modify.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/gl_ES/help/cat_move.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/gl_ES/help/cat_options.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/gl_ES/help/cat_perm.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/gl_ES/help/configuration.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/gl_ES/help/extend_for_templates.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/gl_ES/help/group_list.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/gl_ES/help/help_add_photos.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/gl_ES/help/help_groups.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/gl_ES/help/help_misc.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/gl_ES/help/help_permissions.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/gl_ES/help/help_virtual_links.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/gl_ES/help/history.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/gl_ES/help/maintenance.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/gl_ES/help/notification_by_mail.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/gl_ES/help/permalinks.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/gl_ES/help/photos_add_ftp.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/gl_ES/help/search.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/gl_ES/help/synchronize.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/gl_ES/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/gl_ES/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/gl_ES/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/gl_ES/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/gu_IN/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/gu_IN/gu_IN.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/gu_IN/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/he_IL/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/he_IL/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/he_IL/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/he_IL/he_IL.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/he_IL/help/cat_move.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/he_IL/help/help_add_photos.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/he_IL/help_quick_search.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/he_IL/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/he_IL/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/he_IL/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/he_IL/whats_new_15.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/he_IL/whats_new_16.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/hr_HR/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hr_HR/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/hr_HR/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/hr_HR/help/cat_modify.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hr_HR/help/cat_move.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hr_HR/help/cat_options.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hr_HR/help/cat_perm.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hr_HR/help/configuration.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hr_HR/help/extend_for_templates.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hr_HR/help/group_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hr_HR/help/help_add_photos.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hr_HR/help/history.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hr_HR/help/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/hr_HR/help/maintenance.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hr_HR/help/notification_by_mail.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hr_HR/help/permalinks.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hr_HR/help/search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hr_HR/help/synchronize.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hr_HR/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hr_HR/hr_HR.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/hr_HR/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/hr_HR/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/hr_HR/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/hr_HR/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/hu_HU/README.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/hu_HU/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hu_HU/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/hu_HU/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/hu_HU/help/cat_move.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hu_HU/help/cat_options.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/hu_HU/help/cat_perm.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hu_HU/help/configuration.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hu_HU/help/group_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hu_HU/help/help_add_photos.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hu_HU/help/help_groups.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hu_HU/help/help_misc.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hu_HU/help/help_permissions.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hu_HU/help/help_virtual_links.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hu_HU/help/history.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hu_HU/help/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/hu_HU/help/maintenance.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hu_HU/help/notification_by_mail.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hu_HU/help/permalinks.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hu_HU/help/photos_add_ftp.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hu_HU/help/search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hu_HU/help/synchronize.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hu_HU/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/hu_HU/help_quick_search.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/hu_HU/hu_HU.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/hu_HU/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/hu_HU/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/hu_HU/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/hu_HU/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/hu_HU/whats_new_16.lang.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/hy_AM/admin.lang.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/hy_AM/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/hy_AM/hy_AM.jpg
create mode 100755 Piwingo/piwigo-data/piwigo/language/hy_AM/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/hy_AM/iso.txt
create mode 100755 Piwingo/piwigo-data/piwigo/language/hy_AM/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/hy_AM/whats_new_15.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/id_ID/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/id_ID/id_ID.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/id_ID/index.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/id_ID/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/id_ID/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/is_IS/about.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/is_IS/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/is_IS/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/is_IS/help_quick_search.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/is_IS/index.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/is_IS/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/is_IS/is_IS.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/is_IS/iso.txt
create mode 100755 Piwingo/piwigo-data/piwigo/language/is_IS/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/is_IS/whats_new_15.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/is_IS/whats_new_16.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/it_IT/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/it_IT/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/it_IT/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/it_IT/help/cat_modify.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/it_IT/help/cat_move.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/it_IT/help/cat_options.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/it_IT/help/cat_perm.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/it_IT/help/configuration.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/it_IT/help/extend_for_templates.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/it_IT/help/group_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/it_IT/help/help_add_photos.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/it_IT/help/help_groups.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/it_IT/help/help_misc.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/it_IT/help/help_permissions.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/it_IT/help/help_virtual_links.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/it_IT/help/history.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/it_IT/help/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/it_IT/help/maintenance.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/it_IT/help/notification_by_mail.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/it_IT/help/permalinks.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/it_IT/help/photos_add_ftp.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/it_IT/help/quick_search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/it_IT/help/search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/it_IT/help/synchronize.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/it_IT/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/it_IT/help_quick_search.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/it_IT/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/it_IT/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/it_IT/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/it_IT/it_IT.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/it_IT/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/it_IT/whats_new_15.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/it_IT/whats_new_16.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ja_JP/README.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/ja_JP/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ja_JP/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ja_JP/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ja_JP/help/cat_modify.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ja_JP/help/cat_move.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ja_JP/help/cat_options.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ja_JP/help/cat_perm.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ja_JP/help/configuration.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ja_JP/help/extend_for_templates.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ja_JP/help/group_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ja_JP/help/help_add_photos.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ja_JP/help/help_groups.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ja_JP/help/help_misc.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ja_JP/help/help_permissions.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ja_JP/help/help_virtual_links.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ja_JP/help/history.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ja_JP/help/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ja_JP/help/maintenance.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ja_JP/help/notification_by_mail.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ja_JP/help/permalinks.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ja_JP/help/photos_add_ftp.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/ja_JP/help/quick_search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ja_JP/help/search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ja_JP/help/synchronize.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ja_JP/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ja_JP/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ja_JP/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ja_JP/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/ja_JP/ja_JP.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/ja_JP/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ka_GE/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ka_GE/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ka_GE/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ka_GE/help/cat_modify.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ka_GE/help/cat_move.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ka_GE/help/cat_options.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ka_GE/help/cat_perm.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ka_GE/help/configuration.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ka_GE/help/extend_for_templates.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ka_GE/help/group_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ka_GE/help/help_add_photos.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ka_GE/help/help_groups.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ka_GE/help/help_misc.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ka_GE/help/help_permissions.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ka_GE/help/help_virtual_links.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ka_GE/help/history.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ka_GE/help/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ka_GE/help/maintenance.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ka_GE/help/notification_by_mail.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ka_GE/help/permalinks.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ka_GE/help/photos_add_ftp.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ka_GE/help/search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ka_GE/help/synchronize.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ka_GE/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ka_GE/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ka_GE/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ka_GE/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/ka_GE/ka_GE.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/ka_GE/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/km_KH/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/km_KH/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/km_KH/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/km_KH/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/km_KH/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/km_KH/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/km_KH/km_KH.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/km_KH/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/kn_IN/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/kn_IN/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/kn_IN/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/kn_IN/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/kn_IN/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/kn_IN/kn_IN.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/kn_IN/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ko_KR/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ko_KR/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ko_KR/help_quick_search.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ko_KR/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ko_KR/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ko_KR/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/ko_KR/ko_KR.jpg
create mode 100755 Piwingo/piwigo-data/piwigo/language/ko_KR/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ko_KR/whats_new_16.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/kok_IN/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/kok_IN/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/kok_IN/kok_IN.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/lb_LU/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/lb_LU/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/lb_LU/lb_LU.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/lt_LT/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/lt_LT/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/lt_LT/common.lang.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/lt_LT/help/cat_move.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/lt_LT/help/cat_options.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/lt_LT/help/help_virtual_links.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/lt_LT/help/index.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/lt_LT/help/search.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/lt_LT/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/lt_LT/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/lt_LT/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/lt_LT/lt_LT.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/lt_LT/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/lv_LV/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/lv_LV/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/lv_LV/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/lv_LV/help/cat_modify.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/lv_LV/help/cat_move.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/lv_LV/help/cat_options.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/lv_LV/help/cat_perm.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/lv_LV/help/configuration.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/lv_LV/help/extend_for_templates.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/lv_LV/help/group_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/lv_LV/help/help_add_photos.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/lv_LV/help/help_groups.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/lv_LV/help/help_misc.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/lv_LV/help/help_permissions.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/lv_LV/help/help_virtual_links.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/lv_LV/help/history.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/lv_LV/help/maintenance.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/lv_LV/help/notification_by_mail.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/lv_LV/help/permalinks.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/lv_LV/help/photos_add_ftp.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/lv_LV/help/quick_search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/lv_LV/help/search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/lv_LV/help/synchronize.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/lv_LV/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/lv_LV/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/lv_LV/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/lv_LV/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/lv_LV/lv_LV.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/lv_LV/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/mk_MK/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/mk_MK/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/mk_MK/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/mk_MK/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/mk_MK/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/mk_MK/mk_MK.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/mn_MN/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/mn_MN/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/mn_MN/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/mn_MN/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/mn_MN/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/mn_MN/mn_MN.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/mn_MN/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ms_MY/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ms_MY/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/ms_MY/ms_MY.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/nb_NO/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nb_NO/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/nb_NO/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/nb_NO/help/cat_modify.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nb_NO/help/cat_move.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nb_NO/help/cat_options.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nb_NO/help/cat_perm.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nb_NO/help/configuration.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nb_NO/help/extend_for_templates.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nb_NO/help/group_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nb_NO/help/help_add_photos.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nb_NO/help/help_groups.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nb_NO/help/help_misc.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nb_NO/help/help_permissions.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nb_NO/help/help_virtual_links.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nb_NO/help/history.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nb_NO/help/maintenance.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nb_NO/help/notification_by_mail.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nb_NO/help/permalinks.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nb_NO/help/photos_add_ftp.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/nb_NO/help/quick_search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nb_NO/help/search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nb_NO/help/synchronize.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nb_NO/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nb_NO/help_quick_search.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/nb_NO/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/nb_NO/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/nb_NO/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/nb_NO/nb_NO.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/nb_NO/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/nb_NO/whats_new_15.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/nb_NO/whats_new_16.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/nl_NL/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nl_NL/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/nl_NL/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/nl_NL/help/cat_modify.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nl_NL/help/cat_move.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nl_NL/help/cat_options.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nl_NL/help/cat_perm.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nl_NL/help/configuration.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nl_NL/help/extend_for_templates.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nl_NL/help/group_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nl_NL/help/help_add_photos.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nl_NL/help/help_groups.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nl_NL/help/help_misc.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nl_NL/help/help_permissions.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nl_NL/help/help_virtual_links.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nl_NL/help/history.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nl_NL/help/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/nl_NL/help/maintenance.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nl_NL/help/notification_by_mail.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nl_NL/help/permalinks.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nl_NL/help/photos_add_ftp.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/nl_NL/help/quick_search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nl_NL/help/search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nl_NL/help/synchronize.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nl_NL/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nl_NL/help_quick_search.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/nl_NL/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/nl_NL/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/nl_NL/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/nl_NL/nl_NL.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/nl_NL/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/nl_NL/whats_new_15.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/nl_NL/whats_new_16.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/nn_NO/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nn_NO/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/nn_NO/common.lang.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/nn_NO/help/cat_modify.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/nn_NO/help/cat_move.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/nn_NO/help/cat_options.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/nn_NO/help/cat_perm.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/nn_NO/help/help_add_photos.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/nn_NO/help/help_groups.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/nn_NO/help/help_misc.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/nn_NO/help/help_virtual_links.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/nn_NO/help/history.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/nn_NO/help/notification_by_mail.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/nn_NO/help/permalinks.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/nn_NO/help/photos_add_ftp.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/nn_NO/help/search.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/nn_NO/help/synchronize.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/nn_NO/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/nn_NO/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/nn_NO/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/nn_NO/nn_NO.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/nn_NO/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/pl_PL/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pl_PL/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/pl_PL/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/pl_PL/help/cat_modify.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pl_PL/help/cat_move.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pl_PL/help/cat_options.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pl_PL/help/cat_perm.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pl_PL/help/configuration.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pl_PL/help/extend_for_templates.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pl_PL/help/group_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pl_PL/help/help_add_photos.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pl_PL/help/help_groups.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pl_PL/help/help_misc.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pl_PL/help/help_permissions.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pl_PL/help/help_virtual_links.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pl_PL/help/history.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pl_PL/help/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/pl_PL/help/maintenance.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pl_PL/help/notification_by_mail.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pl_PL/help/permalinks.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pl_PL/help/photos_add_ftp.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/pl_PL/help/quick_search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pl_PL/help/search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pl_PL/help/synchronize.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pl_PL/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pl_PL/help_quick_search.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/pl_PL/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/pl_PL/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/pl_PL/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/pl_PL/pl_PL.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/pl_PL/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/pl_PL/whats_new_15.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/pl_PL/whats_new_16.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/pt_BR/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pt_BR/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/pt_BR/common.lang.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/pt_BR/help/cat_modify.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/pt_BR/help/cat_move.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/pt_BR/help/cat_options.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/pt_BR/help/cat_perm.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/pt_BR/help/configuration.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/pt_BR/help/extend_for_templates.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/pt_BR/help/group_list.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/pt_BR/help/help_add_photos.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pt_BR/help/help_groups.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pt_BR/help/help_misc.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pt_BR/help/help_permissions.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pt_BR/help/help_virtual_links.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/pt_BR/help/history.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/pt_BR/help/maintenance.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/pt_BR/help/notification_by_mail.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/pt_BR/help/permalinks.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pt_BR/help/photos_add_ftp.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/pt_BR/help/quick_search.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/pt_BR/help/search.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/pt_BR/help/synchronize.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/pt_BR/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pt_BR/help_quick_search.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/pt_BR/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/pt_BR/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/pt_BR/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/pt_BR/pt_BR.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/pt_BR/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/pt_BR/whats_new_15.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/pt_BR/whats_new_16.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/pt_PT/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pt_PT/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/pt_PT/common.lang.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/pt_PT/help/cat_modify.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/pt_PT/help/cat_move.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/pt_PT/help/cat_options.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/pt_PT/help/cat_perm.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/pt_PT/help/configuration.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/pt_PT/help/extend_for_templates.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/pt_PT/help/group_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pt_PT/help/help_add_photos.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pt_PT/help/help_groups.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pt_PT/help/help_misc.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pt_PT/help/help_permissions.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pt_PT/help/help_virtual_links.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/pt_PT/help/history.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/pt_PT/help/maintenance.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/pt_PT/help/notification_by_mail.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/pt_PT/help/permalinks.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pt_PT/help/photos_add_ftp.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/pt_PT/help/search.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/pt_PT/help/synchronize.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/pt_PT/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/pt_PT/help_quick_search.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/pt_PT/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/pt_PT/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/pt_PT/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/pt_PT/pt_PT.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/pt_PT/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/pt_PT/whats_new_16.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ro_RO/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ro_RO/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ro_RO/common.lang.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/ro_RO/help/cat_modify.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ro_RO/help/cat_move.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/ro_RO/help/cat_options.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/ro_RO/help/help_add_photos.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/ro_RO/help/help_groups.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/ro_RO/help/help_misc.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ro_RO/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ro_RO/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ro_RO/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/ro_RO/ro_RO.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/ro_RO/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ru_RU/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ru_RU/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ru_RU/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ru_RU/help/cat_modify.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ru_RU/help/cat_move.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ru_RU/help/cat_options.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ru_RU/help/cat_perm.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ru_RU/help/configuration.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ru_RU/help/extend_for_templates.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ru_RU/help/group_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ru_RU/help/help_add_photos.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ru_RU/help/help_groups.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ru_RU/help/help_misc.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ru_RU/help/help_permissions.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ru_RU/help/help_virtual_links.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ru_RU/help/history.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ru_RU/help/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ru_RU/help/maintenance.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ru_RU/help/notification_by_mail.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ru_RU/help/permalinks.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ru_RU/help/photos_add_ftp.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/ru_RU/help/quick_search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ru_RU/help/search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ru_RU/help/synchronize.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ru_RU/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/ru_RU/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ru_RU/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ru_RU/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/ru_RU/ru_RU.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/ru_RU/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ru_RU/whats_new_15.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ru_RU/whats_new_16.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/sh_RS/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/sh_RS/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/sh_RS/common.lang.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/sh_RS/help/cat_modify.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/sh_RS/help/help_add_photos.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/sh_RS/help/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/sh_RS/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/sh_RS/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/sh_RS/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/sh_RS/sh_RS.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/sh_RS/sr_RS.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/sh_RS/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/sk_SK/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/sk_SK/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/sk_SK/common.lang.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/sk_SK/help/cat_modify.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sk_SK/help/cat_move.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sk_SK/help/cat_options.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sk_SK/help/cat_perm.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sk_SK/help/configuration.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sk_SK/help/extend_for_templates.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sk_SK/help/group_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/sk_SK/help/help_add_photos.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/sk_SK/help/help_groups.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/sk_SK/help/help_misc.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/sk_SK/help/help_permissions.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/sk_SK/help/help_virtual_links.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sk_SK/help/history.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/sk_SK/help/index.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/sk_SK/help/maintenance.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sk_SK/help/notification_by_mail.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sk_SK/help/permalinks.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/sk_SK/help/photos_add_ftp.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sk_SK/help/search.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sk_SK/help/synchronize.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sk_SK/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/sk_SK/help_quick_search.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/sk_SK/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/sk_SK/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/sk_SK/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/sk_SK/sk_SK.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/sk_SK/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/sk_SK/whats_new_15.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/sk_SK/whats_new_16.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/sl_SI/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/sl_SI/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/sl_SI/common.lang.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/sl_SI/help/cat_modify.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sl_SI/help/cat_move.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sl_SI/help/cat_options.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sl_SI/help/cat_perm.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sl_SI/help/configuration.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sl_SI/help/group_list.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sl_SI/help/help_add_photos.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sl_SI/help/help_groups.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sl_SI/help/help_misc.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sl_SI/help/help_permissions.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sl_SI/help/help_virtual_links.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sl_SI/help/history.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sl_SI/help/notification_by_mail.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sl_SI/help/permalinks.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sl_SI/help/quick_search.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sl_SI/help/search.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sl_SI/help/synchronize.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sl_SI/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/sl_SI/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/sl_SI/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/sl_SI/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/sl_SI/sl_SI.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/sl_SI/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/sr_RS/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/sr_RS/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/sr_RS/common.lang.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/sr_RS/help/cat_move.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sr_RS/help/group_list.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sr_RS/help/help_groups.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sr_RS/help/search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/sr_RS/help_quick_search.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/sr_RS/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/sr_RS/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/sr_RS/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/sr_RS/sr_RS.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/sr_RS/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/sr_RS/whats_new_15.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/sv_SE/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/sv_SE/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/sv_SE/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/sv_SE/help/cat_modify.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/sv_SE/help/cat_move.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/sv_SE/help/cat_options.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/sv_SE/help/cat_perm.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/sv_SE/help/configuration.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sv_SE/help/extend_for_templates.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/sv_SE/help/group_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/sv_SE/help/help_add_photos.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/sv_SE/help/help_groups.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sv_SE/help/help_misc.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/sv_SE/help/help_permissions.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sv_SE/help/help_virtual_links.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sv_SE/help/history.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/sv_SE/help/index.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/sv_SE/help/maintenance.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sv_SE/help/notification_by_mail.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sv_SE/help/permalinks.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sv_SE/help/photos_add_ftp.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sv_SE/help/quick_search.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sv_SE/help/search.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/sv_SE/help/synchronize.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/sv_SE/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/sv_SE/help_quick_search.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/sv_SE/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/sv_SE/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/sv_SE/sv_SE.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/sv_SE/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/sv_SE/whats_new_15.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/sv_SE/whats_new_16.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ta_IN/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ta_IN/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ta_IN/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/ta_IN/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/ta_IN/ta_IN.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/ta_IN/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/te_IN/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/te_IN/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/te_IN/te_IN.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/th_TH/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/th_TH/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/th_TH/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/th_TH/help/index.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/th_TH/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/th_TH/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/th_TH/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/th_TH/th_TH.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/th_TH/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/tr_TR/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/tr_TR/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/tr_TR/common.lang.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/tr_TR/help/cat_modify.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/tr_TR/help/cat_move.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/tr_TR/help/cat_options.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/tr_TR/help/cat_perm.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/tr_TR/help/configuration.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/tr_TR/help/extend_for_templates.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/tr_TR/help/group_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/tr_TR/help/help_add_photos.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/tr_TR/help/help_groups.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/tr_TR/help/help_misc.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/tr_TR/help/help_permissions.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/tr_TR/help/help_virtual_links.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/tr_TR/help/history.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/tr_TR/help/maintenance.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/tr_TR/help/notification_by_mail.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/tr_TR/help/permalinks.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/tr_TR/help/photos_add_ftp.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/tr_TR/help/quick_search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/tr_TR/help/search.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/tr_TR/help/synchronize.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/tr_TR/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/tr_TR/help_quick_search.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/tr_TR/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/tr_TR/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/tr_TR/tr_TR.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/tr_TR/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/tr_TR/whats_new_15.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/tr_TR/whats_new_16.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/uk_UA/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/uk_UA/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/uk_UA/common.lang.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/uk_UA/help/cat_modify.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/uk_UA/help/cat_move.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/uk_UA/help/cat_options.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/uk_UA/help/cat_perm.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/uk_UA/help/configuration.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/uk_UA/help/extend_for_templates.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/uk_UA/help/group_list.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/uk_UA/help/help_add_photos.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/uk_UA/help/help_groups.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/uk_UA/help/help_misc.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/uk_UA/help/help_permissions.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/uk_UA/help/help_virtual_links.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/uk_UA/help/history.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/uk_UA/help/maintenance.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/uk_UA/help/notification_by_mail.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/uk_UA/help/permalinks.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/uk_UA/help/photos_add_ftp.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/uk_UA/help/quick_search.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/uk_UA/help/search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/uk_UA/help/synchronize.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/uk_UA/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/uk_UA/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/uk_UA/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/uk_UA/uk_UA.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/uk_UA/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/vi_VN/README.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/vi_VN/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/vi_VN/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/vi_VN/common.lang.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/vi_VN/help/group_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/vi_VN/help/help_add_photos.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/vi_VN/help/help_misc.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/vi_VN/help/index.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/vi_VN/help/quick_search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/vi_VN/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/vi_VN/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/vi_VN/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/vi_VN/vi_VN.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/vi_VN/whats_new_15.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/wo_SN/common.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/wo_SN/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/wo_SN/wo_SN.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_CN/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_CN/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_CN/common.lang.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/zh_CN/help/cat_modify.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_CN/help/cat_move.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_CN/help/cat_options.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_CN/help/cat_perm.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_CN/help/configuration.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/zh_CN/help/extend_for_templates.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_CN/help/group_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_CN/help/help_add_photos.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_CN/help/help_groups.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_CN/help/help_misc.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_CN/help/help_permissions.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_CN/help/help_virtual_links.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/zh_CN/help/history.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_CN/help/maintenance.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_CN/help/notification_by_mail.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_CN/help/permalinks.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_CN/help/photos_add_ftp.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/zh_CN/help/quick_search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_CN/help/search.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_CN/help/synchronize.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/zh_CN/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_CN/help_quick_search.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_CN/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_CN/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_CN/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_CN/whats_new_15.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_CN/whats_new_16.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_CN/zh_CN.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_HK/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_HK/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_HK/common.lang.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/zh_HK/help/cat_move.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/zh_HK/help/cat_options.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/zh_HK/help/cat_perm.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_HK/help/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_HK/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_HK/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_HK/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_HK/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_HK/zh_HK.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_TW/about.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_TW/admin.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_TW/common.lang.php
create mode 100755 Piwingo/piwigo-data/piwigo/language/zh_TW/help/cat_modify.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/zh_TW/help/cat_move.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/zh_TW/help/cat_options.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/zh_TW/help/cat_perm.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/zh_TW/help/configuration.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/zh_TW/help/extend_for_templates.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/zh_TW/help/group_list.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/zh_TW/help/help_add_photos.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/zh_TW/help/help_groups.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/zh_TW/help/help_misc.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/zh_TW/help/help_permissions.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/zh_TW/help/help_virtual_links.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/zh_TW/help/history.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/zh_TW/help/maintenance.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/zh_TW/help/notification_by_mail.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/zh_TW/help/permalinks.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/zh_TW/help/photos_add_ftp.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/zh_TW/help/quick_search.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/zh_TW/help/search.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/zh_TW/help/synchronize.html
create mode 100755 Piwingo/piwigo-data/piwigo/language/zh_TW/help/user_list.html
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_TW/help_quick_search.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_TW/install.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_TW/iso.txt
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_TW/upgrade.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_TW/whats_new_15.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_TW/whats_new_16.lang.php
create mode 100644 Piwingo/piwigo-data/piwigo/language/zh_TW/zh_TW.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/local/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/nbm.php
create mode 100644 Piwingo/piwigo-data/piwigo/notification.php
create mode 100644 Piwingo/piwigo-data/piwigo/password.php
create mode 100644 Piwingo/piwigo-data/piwigo/picture.php
create mode 100644 Piwingo/piwigo-data/piwigo/plugins/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/popuphelp.php
create mode 100644 Piwingo/piwigo-data/piwigo/profile.php
create mode 100644 Piwingo/piwigo-data/piwigo/qsearch.php
create mode 100644 Piwingo/piwigo-data/piwigo/random.php
create mode 100644 Piwingo/piwigo-data/piwigo/register.php
create mode 100644 Piwingo/piwigo-data/piwigo/search.php
create mode 100644 Piwingo/piwigo-data/piwigo/tags.php
create mode 100644 Piwingo/piwigo-data/piwigo/template-extension/distributed/samples/my-picture.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/template-extension/distributed/samples/my-thumbnails.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/template-extension/distributed/samples/my-thumbnails2.css
create mode 100644 Piwingo/piwigo-data/piwigo/template-extension/distributed/samples/my-thumbnails2.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/template-extension/distributed/samples/titling_categories.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/template-extension/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/template-extension/yoga/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/template-extension/yoga/local/README
create mode 100644 Piwingo/piwigo-data/piwigo/template-extension/yoga/local/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/css/clear-search.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/css/dark-search.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/css/help/quick_search.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/css/search.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/fix-ie5-ie6.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/fix-ie7.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/fix-khtml.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/datepicker.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/errors.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/errors_small.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/favicon.ico
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/img_small.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/infos.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/mimetypes/afdesign.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/mimetypes/afphoto.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/mimetypes/afpub.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/mimetypes/ai.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/mimetypes/avi.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/mimetypes/doc.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/mimetypes/docx.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/mimetypes/idml.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/mimetypes/indd.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/mimetypes/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/mimetypes/mov.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/mimetypes/mp3.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/mimetypes/mp4.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/mimetypes/mpg.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/mimetypes/ogg.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/mimetypes/ppt.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/mimetypes/pptx.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/mimetypes/prpoj.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/mimetypes/psd.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/mimetypes/txt.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/mimetypes/unknown.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/mimetypes/xd.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/mimetypes/xls.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/mimetypes/xlsx.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/mimetypes/zip.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/note.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/piwigo.org-icon 1.svg
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/rating-stars.gif
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/recent.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/recent_by_child.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/remove_s.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/icon/warning-triangle.svg
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/iconset.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/images/ajax-loader-small.gif
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/images/ajax_loader.gif
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/images/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/images/progressbar.gif
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/images/progressbg_black.gif
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/images/progressbg_green.gif
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/images/progressbg_orange.gif
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/images/progressbg_red.gif
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/images/progressbg_yellow.gif
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/jquery.cookie.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/jquery.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/jquery.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/mcs.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/Chart.min.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/Chart.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/Jcrop.gif
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/chosen-sprite.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/chosen-sprite@2x.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/chosen.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/chosen.jquery.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-ar.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-bg.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-bn.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-ca.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-cs.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-da.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-de.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-es.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-et.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-fa.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-fi.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-fr.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-gl.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-gr.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-he.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-hr.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-hu.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-id.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-it.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-ja.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-kr.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-lt.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-lv.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-my.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-nl.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-no.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-pl.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-pt_BR.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-ro.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-ru.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-si.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-sk.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-sr.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-sv.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-tr.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-uk.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-zh_CN.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/i18n/jquery.colorbox-zh_TW.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/style1/colorbox.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/style1/images/border.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/style1/images/controls.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/style1/images/loading.gif
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/style1/images/loading_background.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/style1/images/overlay.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/style2/colorbox.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/style2/images/controls.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/style2/images/loading.gif
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/style3/colorbox.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/style3/images/controls.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/style3/images/loading.gif
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/style4/colorbox.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/style4/images/border1.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/style4/images/border2.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/style4/images/loading.gif
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/style5/colorbox.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/style5/images/border.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/style5/images/controls.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/style5/images/loading.gif
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/colorbox/style5/images/loading_background.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/datatables/css/jquery.dataTables.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/datatables/images/sort_asc.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/datatables/images/sort_asc_disabled.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/datatables/images/sort_both.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/datatables/images/sort_desc.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/datatables/images/sort_desc_disabled.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/jgrowl-alert.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/jgrowl-check.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/jgrowl-error.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/jqtree.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/jquery-confirm.min.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/jquery-confirm.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/jquery.Jcrop.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/jquery.Jcrop.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/jquery.Jcrop.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/jquery.ajaxmanager.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/jquery.autogrow-textarea.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/jquery.cluetip.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/jquery.colorbox.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/jquery.dataTables.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/jquery.jgrowl.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/jquery.jgrowl_minimized.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/jquery.progressbar.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/jquery.progressbar.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/jquery.sort.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/jquery.tipTip.minified.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/jquery.tokeninput.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/jquery.tokeninput.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/moment-with-locales.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/piecon.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/Moxie.swf
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/Moxie.xap
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/ar.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/az.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/bs.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/cs.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/cy.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/da.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/de.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/el.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/en.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/es.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/et.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/fa.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/fi.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/fr.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/he.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/hr.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/hu.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/hy.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/id.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/it.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/ja.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/ka.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/kk.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/km.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/ko.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/lt.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/lv.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/mn.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/ms.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/nl.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/pl.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/pt_BR.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/ro.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/ru.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/sk.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/sq.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/sr.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/sr_RS.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/sv.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/th_TH.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/tr.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/uk_UA.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/zh_CN.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/i18n/zh_TW.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/jquery.plupload.queue/css/jquery.plupload.queue.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/jquery.plupload.queue/img/backgrounds.gif
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/jquery.plupload.queue/img/buttons-disabled.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/jquery.plupload.queue/img/buttons.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/jquery.plupload.queue/img/delete.gif
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/jquery.plupload.queue/img/done.gif
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/jquery.plupload.queue/img/error.gif
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/jquery.plupload.queue/img/throbber.gif
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/jquery.plupload.queue/img/transp50.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/jquery.plupload.queue/jquery.plupload.queue.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/jquery.plupload.queue/jquery.plupload.queue.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/jquery.ui.plupload/css/jquery.ui.plupload.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/jquery.ui.plupload/css/jquery.ui.plupload.css.orig
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/jquery.ui.plupload/img/loading.gif
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/jquery.ui.plupload/img/plupload.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/jquery.ui.plupload/jquery.ui.plupload.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/jquery.ui.plupload/jquery.ui.plupload.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/moxie.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/moxie.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/plupload.dev.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/plupload.full.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/plupload/plupload.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/selectize.clear.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/selectize.dark.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/selectize.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/tree.jquery.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/plugins/underscore.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/pngfix.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/rating.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/scripts.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/switchbox.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/thumbnails.loader.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery-ui-i18n.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-af.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-ar-DZ.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-ar.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-az.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-bg.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-bs.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-ca.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-cs.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-cy-GB.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-da.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-de.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-el.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-en-AU.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-en-GB.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-en-NZ.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-eo.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-es.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-et.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-eu.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-fa.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-fi.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-fo.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-fr-CH.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-fr.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-gl.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-he.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-hi.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-hr.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-hu.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-hy.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-id.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-is.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-it.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-ja.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-ka.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-kk.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-km.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-ko.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-lb.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-lt.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-lv.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-mk.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-ml.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-ms.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-nl.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-no.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-pl.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-pt-BR.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-pt.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-rm.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-ro.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-ru.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-sk.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-sl.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-sq.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-sr-SR.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-sr.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-sv.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-ta.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-th.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-tj.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-tr.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-uk.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-vi.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-zh-CN.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-zh-HK.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.datepicker-zh-TW.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-af.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-am.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-bg.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-ca.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-cs.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-da.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-de.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-el.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-es.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-et.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-eu.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-fi.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-fr.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-gl.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-he.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-hr.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-hu.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-id.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-it.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-ja.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-ko.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-lt.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-nl.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-no.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-pl.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-pt-BR.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-pt.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-ro.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-ru.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-sk.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-sr-RS.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-sr-YU.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-sv.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-th.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-tr.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-uk.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-vi.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-zh-CN.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/i18n/jquery.ui.timepicker-zh-TW.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.accordion.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.autocomplete.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.button.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.core.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.datepicker.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.dialog.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.draggable.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.droppable.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.effect-blind.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.effect-bounce.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.effect-clip.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.effect-drop.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.effect-explode.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.effect-fade.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.effect-fold.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.effect-highlight.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.effect-pulsate.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.effect-scale.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.effect-shake.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.effect-slide.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.effect-transfer.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.effect.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.menu.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.mouse.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.position.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.progressbar.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.resizable.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.selectable.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.slider.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.sortable.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.spinner.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.tabs.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.timepicker-addon.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.tooltip.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/jquery.ui.widget.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.accordion.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.autocomplete.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.button.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.core.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.datepicker.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.dialog.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.draggable.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.droppable.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.effect-blind.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.effect-bounce.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.effect-clip.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.effect-drop.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.effect-explode.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.effect-fade.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.effect-fold.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.effect-highlight.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.effect-pulsate.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.effect-scale.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.effect-shake.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.effect-slide.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.effect-transfer.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.effect.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.menu.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.mouse.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.position.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.progressbar.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.resizable.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.selectable.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.slider.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.sortable.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.spinner.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.tabs.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.timepicker-addon.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.tooltip.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/minified/jquery.ui.widget.min.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/theme/images/animated-overlay.gif
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/theme/images/ui-bg_flat_0_aaaaaa_40x100.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/theme/images/ui-bg_flat_75_ffffff_40x100.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/theme/images/ui-bg_glass_55_fbf9ee_1x400.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/theme/images/ui-bg_glass_65_ffffff_1x400.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/theme/images/ui-bg_glass_75_dadada_1x400.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/theme/images/ui-bg_glass_75_e6e6e6_1x400.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/theme/images/ui-bg_glass_95_fef1ec_1x400.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/theme/images/ui-bg_highlight-soft_75_cccccc_1x100.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/theme/images/ui-icons_222222_256x240.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/theme/images/ui-icons_2e83ff_256x240.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/theme/images/ui-icons_454545_256x240.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/theme/images/ui-icons_888888_256x240.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/theme/images/ui-icons_cd0a0a_256x240.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/theme/jquery.ui.accordion.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/theme/jquery.ui.all.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/theme/jquery.ui.autocomplete.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/theme/jquery.ui.base.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/theme/jquery.ui.button.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/theme/jquery.ui.core.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/theme/jquery.ui.datepicker.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/theme/jquery.ui.dialog.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/theme/jquery.ui.menu.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/theme/jquery.ui.progressbar.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/theme/jquery.ui.resizable.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/theme/jquery.ui.selectable.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/theme/jquery.ui.slider.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/theme/jquery.ui.spinner.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/theme/jquery.ui.tabs.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/theme/jquery.ui.theme.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/theme/jquery.ui.timepicker-addon.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/js/ui/theme/jquery.ui.tooltip.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/local_head.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/print.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/s26/index.htm
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/s26/outline_005e89.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/s26/outline_808060.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/s26/outline_808080.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/s26/outline_ff3363.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/s26/outline_ff7700.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/s26/outline_ffff80.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/s26/outline_ffffff.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/about.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/comment_list.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/comments.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/footer.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/header.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/help/quick_search.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/identification.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/include/autosize.inc.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/include/colorbox.inc.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/include/related_tags.inc.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/include/search_filters.inc.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/include/selected_tags.inc.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/index.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/infos_errors.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/mail/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/mail/screenshot-clear.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/mail/screenshot-dark.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/mail/text/html/cat_group_info.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/mail/text/html/footer.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/mail/text/html/global-mail-css.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/mail/text/html/header.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/mail/text/html/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/mail/text/html/mail-css-clear.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/mail/text/html/mail-css-dark.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/mail/text/html/notification_admin.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/mail/text/html/notification_by_mail.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/mail/text/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/mail/text/plain/cat_group_info.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/mail/text/plain/footer.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/mail/text/plain/header.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/mail/text/plain/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/mail/text/plain/notification_admin.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/mail/text/plain/notification_by_mail.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/mainpage_categories.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/menubar.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/menubar_categories.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/menubar_identification.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/menubar_links.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/menubar_menu.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/menubar_related_categories.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/menubar_specials.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/menubar_tags.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/month_calendar.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/navigation_bar.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/nbm.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/no_photo_yet.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/notification.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/password.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/picture.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/picture_content.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/picture_nav_buttons.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/popuphelp.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/profile.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/profile_content.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/redirect.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/register.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/search.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/search_rules.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/slideshow.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/tags.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/template/thumbnails.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/theme.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/themeconf.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/vendor/fontello/LICENSE.txt
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/vendor/fontello/README.txt
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/vendor/fontello/config.json
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/vendor/fontello/css/animation.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/vendor/fontello/css/gallery-icon-codes.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/vendor/fontello/css/gallery-icon-embedded.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/vendor/fontello/css/gallery-icon-ie7-codes.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/vendor/fontello/css/gallery-icon-ie7.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/vendor/fontello/css/gallery-icon.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/vendor/fontello/demo.html
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/vendor/fontello/font/gallery-icon.eot
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/vendor/fontello/font/gallery-icon.svg
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/vendor/fontello/font/gallery-icon.ttf
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/vendor/fontello/font/gallery-icon.woff
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/vendor/fontello/font/gallery-icon.woff2
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/watermarks/Owned_Stamp.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/watermarks/Sample.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/watermarks/copyright-2023.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/watermarks/copyright-2024.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/default/watermarks/copyright.png
create mode 100644 Piwingo/piwigo-data/piwigo/themes/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/fonts/OpenSans-VariableFont_wdth,wght.ttf
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/images/piwigo_logo.svg
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/images/piwigo_logo_dark.svg
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/js/profile.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/js/standard_pages.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/js/toaster.js
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/cadmium.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/cobalt.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/dark-cadmium.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/dark-cobalt.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/dark-default.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/dark-fuchsia.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/dark-green.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/dark-lime.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/dark-purple.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/dark-red.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/dark-sienna.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/dark-silver.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/dark-teal.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/default.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/fuchsia.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/green.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/light-cadmium.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/light-cobalt.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/light-default.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/light-fuchsia.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/light-green.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/light-lime.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/light-purple.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/light-red.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/light-sienna.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/light-silver.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/light-teal.jpg
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/lime.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/purple.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/red.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/sienna.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/silver.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/skins/teal.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/template/footer.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/template/header.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/template/identification.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/template/password.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/template/profile.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/template/register.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/template/toaster.tpl
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/theme.css
create mode 100644 Piwingo/piwigo-data/piwigo/themes/standard_pages/themeconf.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/tools/fill_history.pl
create mode 100644 Piwingo/piwigo-data/piwigo/tools/github_issues.php
create mode 100644 Piwingo/piwigo-data/piwigo/tools/index.php
create mode 100644 Piwingo/piwigo-data/piwigo/tools/language/translation_validated.inc.php
create mode 100644 Piwingo/piwigo-data/piwigo/tools/metadata.php
create mode 100644 Piwingo/piwigo-data/piwigo/tools/missing_keys.pl
create mode 100644 Piwingo/piwigo-data/piwigo/tools/piwigo_addSimple.pl
create mode 100644 Piwingo/piwigo-data/piwigo/tools/piwigo_remote.pl
create mode 100644 Piwingo/piwigo-data/piwigo/tools/piwigo_upload.pl
create mode 100755 Piwingo/piwigo-data/piwigo/tools/pwg_rel_create.sh
create mode 100644 Piwingo/piwigo-data/piwigo/tools/remote_sync.pl
create mode 100644 Piwingo/piwigo-data/piwigo/tools/replace_version.pl
create mode 100644 Piwingo/piwigo-data/piwigo/tools/test_piwigo.php
create mode 100644 Piwingo/piwigo-data/piwigo/tools/translation_analysis.php
create mode 100644 Piwingo/piwigo-data/piwigo/tools/triggers_list.php
create mode 100644 Piwingo/piwigo-data/piwigo/tools/ws.htm
create mode 100644 Piwingo/piwigo-data/piwigo/tools/ws/jquery.json-viewer.css
create mode 100644 Piwingo/piwigo-data/piwigo/tools/ws/jquery.json-viewer.js
create mode 100644 Piwingo/piwigo-data/piwigo/tools/ws/piwigo-logo-minimal.svg
create mode 100644 Piwingo/piwigo-data/piwigo/tools/ws/ws.css
create mode 100644 Piwingo/piwigo-data/piwigo/tools/ws/ws.js
create mode 100644 Piwingo/piwigo-data/piwigo/upgrade.php
create mode 100644 Piwingo/piwigo-data/piwigo/upgrade_feed.php
create mode 100644 Piwingo/piwigo-data/piwigo/ws.php
create mode 100644 copyparty/.env
create mode 100755 copyparty/copyparty/copyparty.conf
create mode 100644 copyparty/docker-compose.yml
create mode 100755 copyparty/get_hashes
create mode 100644 gameyfin/.env
create mode 100644 gameyfin/docker-compose.yml
create mode 100644 gitea-runner/.runner
create mode 100644 gitea-runner/.runner.lock
create mode 100644 gitea-runner/README.md
create mode 100755 gitea-runner/runner
create mode 100644 gitea/.env
create mode 100644 gitea/docker-compose.yml
create mode 100644 hoodik/.env
create mode 100644 hoodik/docker-compose.yml
create mode 100644 immich/.env
create mode 100644 immich/docker-compose.yml
create mode 100644 jellyfin/.env
create mode 100644 jellyfin/docker-compose.yml
create mode 100644 navidrome/.env
create mode 100644 navidrome/docker-compose.yaml
create mode 100755 neoforge/cm
create mode 100644 neoforge/docker-compose.yml
create mode 100644 neoforge/mc/.neoforge-manifest.json
create mode 100644 neoforge/mc/.rcon-cli.env
create mode 100644 neoforge/mc/.rcon-cli.yaml
create mode 100644 neoforge/mc/.run-neoforge.env
create mode 100644 nextcloud/docker-compose.yml
create mode 100644 owncloud-docker-server/.env
create mode 100644 owncloud-docker-server/docker-compose.yml
create mode 100644 portainer/docker-compose.yml
create mode 100755 portal-runner-convert/docker-compose.yml
create mode 100644 rstack/.env
create mode 100644 rstack/docker-compose.yml
create mode 100644 seafile/.env
create mode 100644 seafile/docker-compose.yml
create mode 100644 synapse/config.yaml
create mode 100644 synapse/docker-compose.yml
diff --git a/Piwingo/.env b/Piwingo/.env
new file mode 100644
index 0000000..a581cbb
--- /dev/null
+++ b/Piwingo/.env
@@ -0,0 +1,3 @@
+piwigo_port=8010
+db_user_password=clippylovesyou
+timezone=MST
diff --git a/Piwingo/compose.yaml b/Piwingo/compose.yaml
new file mode 100644
index 0000000..6ee1746
--- /dev/null
+++ b/Piwingo/compose.yaml
@@ -0,0 +1,35 @@
+networks:
+ piwigo-network:
+ external: false
+
+services:
+ piwigo-main:
+ image: piwigo/piwigo:latest
+ restart: no
+ environment:
+ - TZ=${timezone}
+ - PIWIGO_UID=${PIWIGO_UID}
+ - PIWIGO_GID=${PIWIGO_GID}
+ networks:
+ - piwigo-network
+ ports:
+ - ${piwigo_port}:80
+ depends_on:
+ - piwigo-db
+ volumes:
+ - ./piwigo-data/piwigo:/var/www/html/piwigo/
+ - ./piwigo-data/scripts:/usr/local/bin/scripts/
+ piwigo-db:
+ image: docker.io/library/mariadb:lts
+ restart: no
+ environment:
+ - MARIADB_RANDOM_ROOT_PASSWORD=true
+ - MARIADB_USER=piwigodb_user
+ - MARIADB_DATABASE=piwigodb
+ # Defined in .env
+ - MARIADB_PASSWORD=${db_user_password}
+ - TZ=${timezone}
+ networks:
+ - piwigo-network
+ volumes:
+ - ./piwigo-data/mysql:/var/lib/mysql
diff --git a/Piwingo/piwigo-data/mysql/mariadb_upgrade_info b/Piwingo/piwigo-data/mysql/mariadb_upgrade_info
new file mode 100644
index 0000000..a4644d6
--- /dev/null
+++ b/Piwingo/piwigo-data/mysql/mariadb_upgrade_info
@@ -0,0 +1 @@
+11.8.6-MariaDB
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/.gitignore b/Piwingo/piwigo-data/piwigo/.gitignore
new file mode 100644
index 0000000..b1d084e
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/.gitignore
@@ -0,0 +1,23 @@
+# Piwigo specific directories
+/_data
+/plugins/*
+!/plugins/index.php
+/themes/*
+!/themes/index.php
+!/themes/default
+!/themes/standard_pages
+/upload
+/galleries/*
+!/galleries/index.php
+/local/*
+!/local/**/index.php
+
+# IntelliJ
+.idea
+*.iml
+*.ipr
+*.iws
+
+# Eclipse
+.settings
+.project
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/COPYING.txt b/Piwingo/piwigo-data/piwigo/COPYING.txt
new file mode 100644
index 0000000..f36d8e8
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/COPYING.txt
@@ -0,0 +1,18 @@
+COPYRIGHT
+
+ Piwigo - a photo library manager
+
+ Copyright(C) 2008-2024 Piwigo Team https://piwigo.org
+ Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net
+ Copyright(C) 2002-2003 Pierrick LE GALL http://pierrick.le-gall.net
+
+
+SOFTWARE LICENSE
+
+ The free software license of Piwigo is GNU General Public License v2
+ or later. See LICENSE.txt to get a full copy.
+
+
+TRADEMARK
+
+ Piwigo is a registered trademark.
diff --git a/Piwingo/piwigo-data/piwigo/LICENSE.txt b/Piwingo/piwigo-data/piwigo/LICENSE.txt
new file mode 100644
index 0000000..d159169
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/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/Piwingo/piwigo-data/piwigo/README.md b/Piwingo/piwigo-data/piwigo/README.md
new file mode 100644
index 0000000..e17c2e7
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/README.md
@@ -0,0 +1,42 @@
+
+
+Manage your photo library. Piwigo is open source photo gallery software for the web. Designed for organisations, teams and individuals.
+
+
+
+The [piwigo.org](https://piwigo.org) website introduces you to Piwigo. You'll find a demo, forums, wiki and news.
+
+## Requirements
+
+ * A webserver (Apache or nginx recommended)
+ * PHP 7.4+. Piwigo can run with PHP 7.0+ but these end-of-life versions are no longer maintained and may expose your site to security vulnerabilities.
+ * MySQL 5 or greater or MariaDB equivalent
+ * ImageMagick (recommended) or PHP GD
+
+## Quick start install
+
+### NetInstall
+
+ * Download the [NetInstall script](https://piwigo.org/download/dlcounter.php?code=netinstall)
+ * Transfer the script to your web space with any FTP client
+ * Open the script in you web browser (for example http://example.com/piwigo-netinstall.php) and follow the steps
+
+[More information](https://piwigo.org/guides/install/netinstall)
+
+### Manual
+
+ * Download the [latest stable version](https://piwigo.org/download/dlcounter.php?code=latest) and unzip it
+ * Transfer everything to your web space with any FTP client
+ * Open your website (for example http://example.com/piwigo) and follow the steps
+
+[More information](https://piwigo.org/guides/install/manual)
+
+If you do not have your own server, consider the [piwigo.com](https://piwigo.com/) hosting solution.
+
+## Contributing
+
+Piwigo is widely driven by its community; if you want to improve the code, fork this repo and submit your changes to the `master` branch. See our [Contribution guide](https://github.com/Piwigo/Piwigo/blob/master/docs/CONTRIBUTING.md).
+
+## License
+
+Piwigo is released under the GPL v2 license. See our [Copying details](https://github.com/Piwigo/Piwigo/blob/master/COPYING.txt).
diff --git a/Piwingo/piwigo-data/piwigo/SECURITY.md b/Piwingo/piwigo-data/piwigo/SECURITY.md
new file mode 100644
index 0000000..ceedd26
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/SECURITY.md
@@ -0,0 +1,36 @@
+# Piwigo Security Policy
+
+The Piwigo team and community take security bugs seriously. We appreciate your efforts
+to responsibly disclose your findings.
+
+## Supported Versions
+
+Security updates will typically only be applied to the latest release. Exceptionally,
+we may release a new version of an old branch but that won't be the standard way we process.
+
+## Reporting a Vulnerability
+
+**Please contact us at [security@piwigo.org](mailto:security@piwigo.org) when you have
+discovered a potential security issue.** Please do not create a public issue for now. At a minimum, your report by email should include the following:
+
+- version of Piwigo, version of PHP, version of MySQL/MariaDB
+- vulnerability description
+- reproduction steps
+
+You will receive a response from us within 72 hours. If the issue is confirmed we will
+then work on fixing it and release a new fixed version of Piwigo, following these steps:
+
+- Confirm the problem and determine the affected versions.
+- Audit code to find any potential similar problems.
+- Prepare a fix for `master` branch and backport it on the current stable branch.
+- Release a new version of Piwigo on its current stable branch as fast as possible, historically within a few days.
+
+## Responsible Disclosure
+
+1. Confirm that the vulnerability applies to a current version and is reproducible.
+2. First share the vulnerability details with us so that users are not put at risk.
+3. Wait before publishing details until everyone has had a chance to update.
+4. Respect the privacy of others.
+
+*Avoid activities that disrupt, degrade, or interrupt our services or compromise other
+users' data, such as spam, brute force attacks, denial of service attacks, and malicious file distribution.*
diff --git a/Piwingo/piwigo-data/piwigo/about.php b/Piwingo/piwigo-data/piwigo/about.php
new file mode 100644
index 0000000..0831201
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/about.php
@@ -0,0 +1,48 @@
+set_filename('about', 'about.tpl');
+
+$template->assign('ABOUT_MESSAGE', load_language('about.html','', array('return'=>true)) );
+
+$theme_about = load_language('about.html', PHPWG_THEMES_PATH.$user['theme'].'/', array('return' => true));
+if ( $theme_about !== false )
+{
+ $template->assign('THEME_ABOUT', $theme_about);
+}
+
+// include menubar
+$themeconf = $template->get_template_vars('themeconf');
+if (!isset($themeconf['hide_menu_on']) OR !in_array('theAboutPage', $themeconf['hide_menu_on']))
+{
+ include( PHPWG_ROOT_PATH.'include/menubar.inc.php');
+}
+
+include(PHPWG_ROOT_PATH.'include/page_header.php');
+flush_page_messages();
+$template->pparse('about');
+include(PHPWG_ROOT_PATH.'include/page_tail.php');
+?>
diff --git a/Piwingo/piwigo-data/piwigo/action.php b/Piwingo/piwigo-data/piwigo/action.php
new file mode 100644
index 0000000..4f3e2fa
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/action.php
@@ -0,0 +1,236 @@
+ restriction)
+$query='
+SELECT id
+ FROM '.CATEGORIES_TABLE.'
+ INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON category_id = id
+ WHERE image_id = '.$_GET['id'].'
+'.get_sql_condition_FandF(
+ array(
+ 'forbidden_categories' => 'category_id',
+ 'forbidden_images' => 'image_id',
+ ),
+ ' AND'
+ ).'
+ LIMIT 1
+;';
+if (!$is_admin_download and pwg_db_num_rows(pwg_query($query))<1 )
+{
+ do_error(401, 'Access denied');
+}
+
+include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php');
+$file='';
+switch ($_GET['part'])
+{
+ case 'e':
+ if ( $src_image->is_original() and !$user['enabled_high'] )
+ {// we have a photo and the user has no access to HD
+ $deriv = new DerivativeImage(IMG_XXLARGE, $src_image);
+ if ( !$deriv->same_as_source() )
+ {
+ do_error(401, 'Access denied e');
+ }
+ }
+ $file = get_element_path($element_info);
+ break;
+ case 'r':
+ $file = original_to_representative( get_element_path($element_info), $element_info['representative_ext'] );
+ break;
+ case 'f' :
+ $file = original_to_format(get_element_path($element_info), $format['ext']);
+ $element_info['file'] = get_filename_wo_extension($element_info['file']).'.'.$format['ext'];
+ break;
+}
+
+if ( empty($file) )
+{
+ do_error(404, 'Requested file not found');
+}
+
+if ($_GET['part'] == 'e') {
+ pwg_log($_GET['id'], 'high');
+}
+else if ($_GET['part'] == 'e')
+{
+ pwg_log($_GET['id'], 'other');
+}
+else if ($_GET['part'] == 'f')
+{
+ pwg_log($_GET['id'], 'high', $format['format_id']);
+}
+
+trigger_notify('loc_action_before_http_headers');
+
+$http_headers = array();
+
+$ctype = null;
+if (!url_is_remote($file))
+{
+ if ( !@is_readable($file) )
+ {
+ do_error(404, "Requested file not found - $file");
+ }
+ $http_headers[] = 'Content-Length: '.@filesize($file);
+ if ( function_exists('mime_content_type') )
+ {
+ $ctype = mime_content_type($file);
+ }
+
+ $gmt_mtime = gmdate('D, d M Y H:i:s', filemtime($file)).' GMT';
+ $http_headers[] = 'Last-Modified: '.$gmt_mtime;
+
+ // following lines would indicate how the client should handle the cache
+ /* $max_age=300;
+ $http_headers[] = 'Expires: '.gmdate('D, d M Y H:i:s', time()+$max_age).' GMT';
+ // HTTP/1.1 only
+ $http_headers[] = 'Cache-Control: private, must-revalidate, max-age='.$max_age;*/
+
+ if ('f' != $_GET['part'] and isset( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) )
+ {
+ set_status_header(304);
+ foreach ($http_headers as $header)
+ {
+ header( $header );
+ }
+ exit();
+ }
+}
+
+if (!isset($ctype))
+{ // give it a guess
+ $ctype = guess_mime_type( get_extension($file) );
+}
+
+$http_headers[] = 'Content-Type: '.$ctype;
+
+if (isset($_GET['download']))
+{
+ $http_headers[] = 'Content-Disposition: attachment; filename="'.htmlspecialchars_decode($element_info['file']).'";';
+ $http_headers[] = 'Content-Transfer-Encoding: binary';
+}
+else
+{
+ $http_headers[] = 'Content-Disposition: inline; filename="'
+ .basename($file).'";';
+}
+
+foreach ($http_headers as $header)
+{
+ header( $header );
+}
+
+// Looking at the safe_mode configuration for execution time
+if (ini_get('safe_mode') == 0)
+{
+ @set_time_limit(0);
+}
+
+// Without clean and flush there may be some image download problems, or image can be corrupted after download
+if (ob_get_length() !== FALSE)
+{
+ ob_flush();
+}
+flush();
+
+@readfile($file);
+
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin.php b/Piwingo/piwigo-data/piwigo/admin.php
new file mode 100644
index 0000000..afa3430
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin.php
@@ -0,0 +1,428 @@
+ 0)
+{
+ $perform_fsqc = false;
+ if (isset($conf['fs_quick_check_last_check']))
+ {
+ if (strtotime($conf['fs_quick_check_last_check']) < strtotime($conf['fs_quick_check_period'].' seconds ago'))
+ {
+ $perform_fsqc = true;
+ }
+ }
+ else
+ {
+ $perform_fsqc = true;
+ }
+
+ if ($perform_fsqc)
+ {
+ fs_quick_check();
+ }
+}
+
+// +-----------------------------------------------------------------------+
+// | Direct actions |
+// +-----------------------------------------------------------------------+
+
+// save plugins_new display order (AJAX action)
+if (isset($_GET['plugins_new_order']))
+{
+ pwg_set_session_var('plugins_new_order', $_GET['plugins_new_order']);
+ exit;
+}
+
+// theme changer
+if (isset($_GET['change_theme']))
+{
+ $admin_themes = array('roma', 'clear');
+ $admin_theme_array = array(userprefs_get_param('admin_theme', 'clear'));
+ $result = array_diff(
+ $admin_themes,
+ $admin_theme_array
+ );
+
+ $new_admin_theme = array_pop(
+ $result
+ );
+
+ userprefs_update_param('admin_theme', $new_admin_theme);
+
+ $url_params = array();
+ foreach (array('page', 'tab', 'section') as $url_param)
+ {
+ if (isset($_GET[$url_param]))
+ {
+ $url_params[] = $url_param.'='.$_GET[$url_param];
+ }
+ }
+
+ $redirect_url = 'admin.php';
+ if (count($url_params) > 0)
+ {
+ $redirect_url.= '?'.implode('&', $url_params);
+ }
+
+ redirect($redirect_url);
+}
+
+// +-----------------------------------------------------------------------+
+// | Synchronize user informations |
+// +-----------------------------------------------------------------------+
+
+// sync_user() is only useful when external authentication is activated
+if ($conf['external_authentification'])
+{
+ sync_users();
+}
+
+// +-----------------------------------------------------------------------+
+// | Variables init |
+// +-----------------------------------------------------------------------+
+
+$change_theme_url = PHPWG_ROOT_PATH.'admin.php?';
+$test_get = $_GET;
+unset($test_get['page']);
+unset($test_get['section']);
+unset($test_get['tag']);
+if (count($test_get) == 0 and !empty($_SERVER['QUERY_STRING']))
+{
+ $change_theme_url.= str_replace('&', '&', $_SERVER['QUERY_STRING']).'&';
+}
+$change_theme_url.= 'change_theme=1';
+
+// ?page=plugin-community-pendings is an clean alias of
+// ?page=plugin§ion=community/admin.php&tab=pendings
+if (isset($_GET['page']) and preg_match('/^plugin-([^-]*)(?:-(.*))?$/', $_GET['page'], $matches))
+{
+ $_GET['page'] = 'plugin';
+
+ if (preg_match('/^piwigo_(videojs|openstreetmap)$/', $matches[1]))
+ {
+ $matches[1] = str_replace('_', '-', $matches[1]);
+ }
+
+ $_GET['section'] = $matches[1].'/admin.php';
+ if (isset($matches[2]))
+ {
+ $_GET['tab'] = $matches[2];
+ }
+}
+
+// ?page=album-134-properties is an clean alias of
+// ?page=album&cat_id=134&tab=properties
+if (isset($_GET['page']) and preg_match('/^album-(\d+)(?:-(.*))?$/', $_GET['page'], $matches))
+{
+ $_GET['page'] = 'album';
+ $_GET['cat_id'] = $matches[1];
+ if (isset($matches[2]))
+ {
+ $_GET['tab'] = $matches[2];
+ }
+}
+
+// ?page=photo-1234-properties is an clean alias of
+// ?page=photo&image_id=1234&tab=properties
+if (isset($_GET['page']) and preg_match('/^photo-(\d+)(?:-(.*))?$/', $_GET['page'], $matches))
+{
+ $_GET['page'] = 'photo';
+ $_GET['image_id'] = $matches[1];
+ if (isset($matches[2]))
+ {
+ $_GET['tab'] = $matches[2];
+ }
+}
+
+if (isset($_GET['page'])
+ and preg_match('/^[a-z_]*$/', $_GET['page'])
+ and is_file(PHPWG_ROOT_PATH.'admin/'.$_GET['page'].'.php'))
+{
+ $page['page'] = $_GET['page'];
+}
+else
+{
+ $page['page'] = 'intro';
+}
+
+$link_start = PHPWG_ROOT_PATH.'admin.php?page=';
+$conf_link = $link_start.'configuration§ion=';
+
+// $_GET['tab'] is often used to perform and
+// include('admin_page_'.$_GET['tab'].'.php') : we need to protect it to
+// avoid any unexpected file inclusion
+check_input_parameter('tab', $_GET, false, '/^[a-zA-Z\d_-]+$/');
+
+// +-----------------------------------------------------------------------+
+// | Template init |
+// +-----------------------------------------------------------------------+
+
+$title = l10n('Piwigo Administration'); // for include/page_header.php
+$page['page_banner'] = ''.l10n('Piwigo Administration').'
';
+$page['body_id'] = 'theAdminPage';
+
+$template->set_filenames(array('admin' => 'admin.tpl'));
+
+$template->assign(
+ array(
+ 'USERNAME' => $user['username'],
+ 'ENABLE_SYNCHRONIZATION' => $conf['enable_synchronization'],
+ 'U_SITE_MANAGER'=> $link_start.'site_manager',
+ 'U_HISTORY_STAT'=> $link_start.'stats&year='.date('Y').'&month='.date('n'),
+ 'U_FAQ'=> $link_start.'help',
+ 'U_SITES'=> $link_start.'remote_site',
+ 'U_MAINTENANCE'=> $link_start.'maintenance',
+ 'U_NOTIFICATION_BY_MAIL'=> $link_start.'notification_by_mail',
+ 'U_CONFIG_GENERAL'=> $link_start.'configuration',
+ 'U_CONFIG_DISPLAY'=> $conf_link.'default',
+ 'U_CONFIG_EXTENTS'=> $link_start.'extend_for_templates',
+ 'U_CONFIG_MENUBAR'=> $link_start.'menubar',
+ 'U_CONFIG_LANGUAGES' => $link_start.'languages',
+ 'U_CONFIG_THEMES'=> $link_start.'themes',
+ 'U_CATEGORIES'=> $link_start.'cat_list',
+ 'U_ALBUMS'=> $link_start.'albums',
+ 'U_CAT_OPTIONS'=> $link_start.'cat_options',
+ 'U_CAT_SEARCH'=> $link_start.'cat_search',
+ 'U_CAT_UPDATE'=> $link_start.'site_update&site=1',
+ 'U_RATING'=> $link_start.'rating',
+ 'U_RECENT_SET'=> $link_start.'batch_manager&filter=prefilter-last_import',
+ 'U_BATCH'=> $link_start.'batch_manager',
+ 'U_TAGS'=> $link_start.'tags',
+ 'U_USERS'=> $link_start.'user_list',
+ 'U_GROUPS'=> $link_start.'group_list',
+ 'U_RETURN'=> get_gallery_home_url(),
+ 'U_ADMIN'=> PHPWG_ROOT_PATH.'admin.php',
+ 'U_LOGOUT'=> PHPWG_ROOT_PATH.'index.php?act=logout',
+ 'U_PLUGINS'=> $link_start.'plugins',
+ 'U_ADD_PHOTOS' => $link_start.'photos_add',
+ 'U_CHANGE_THEME' => $change_theme_url,
+ 'ADMIN_PAGE_TITLE' => 'Piwigo Administration Page',
+ 'ADMIN_PAGE_OBJECT_ID' => '',
+ 'U_SHOW_TEMPLATE_TAB' => $conf['show_template_in_side_menu'],
+ 'SHOW_RATING' => $conf['rate'],
+ )
+ );
+
+if ($conf['enable_core_update'])
+{
+ $template->assign('U_UPDATES', $link_start.'updates');
+}
+
+if ($conf['activate_comments'])
+{
+ $template->assign('U_COMMENTS', $link_start.'comments');
+
+ // pending comments
+ $query = '
+SELECT COUNT(*)
+ FROM '.COMMENTS_TABLE.'
+ WHERE validated=\'false\'
+;';
+ list($nb_comments) = pwg_db_fetch_row(pwg_query($query));
+
+ if ($nb_comments > 0)
+ {
+ $template->assign('NB_PENDING_COMMENTS', $nb_comments);
+ $page['nb_pending_comments'] = $nb_comments;
+ }
+}
+
+// any photo in the caddie?
+$query = '
+SELECT COUNT(*)
+ FROM '.CADDIE_TABLE.'
+ WHERE user_id = '.$user['id'].'
+;';
+list($nb_photos_in_caddie) = pwg_db_fetch_row(pwg_query($query));
+
+if ($nb_photos_in_caddie > 0)
+{
+ $template->assign(
+ array(
+ 'NB_PHOTOS_IN_CADDIE' => $nb_photos_in_caddie,
+ 'U_CADDIE' => $link_start.'batch_manager&filter=prefilter-caddie',
+ )
+ );
+} else {
+ $template->assign(
+ array(
+ 'NB_PHOTOS_IN_CADDIE' => 0,
+ 'U_CADDIE' => '',
+ )
+ );
+}
+
+// any photos with no md5sum ?
+if (in_array($page['page'], array('site_update', 'batch_manager')))
+{
+ $nb_no_md5sum = count(get_photos_no_md5sum());
+
+ if ($nb_no_md5sum > 0)
+ {
+ $page['no_md5sum_number'] = $nb_no_md5sum;
+ }
+}
+
+// only calculate number of orphans on all pages if the number of images is "not huge"
+$page['nb_orphans'] = 0;
+
+list($page['nb_photos_total']) = pwg_db_fetch_row(pwg_query('SELECT COUNT(*) FROM '.IMAGES_TABLE));
+if ($page['nb_photos_total'] < 100000) // 100k is already a big gallery
+{
+ $page['nb_orphans'] = count_orphans();
+}
+
+$template->assign(
+ array(
+ 'NB_ORPHANS' => $page['nb_orphans'],
+ 'U_ORPHANS' => $link_start.'batch_manager&filter=prefilter-no_album',
+ )
+ );
+
+// +-----------------------------------------------------------------------+
+// | Refresh permissions |
+// +-----------------------------------------------------------------------+
+
+// Only for pages witch change permissions
+if (
+ in_array($page['page'],
+ array(
+ 'site_manager', // delete site
+ 'site_update', // ?only POST
+ )
+ )
+ or ( !empty($_POST) and in_array($page['page'],
+ array(
+ 'album', // public/private; lock/unlock, permissions
+ 'albums',
+ 'cat_options', // public/private; lock/unlock
+ 'user_list', // group assoc; user level
+ 'user_perm',
+ )
+ )
+ )
+ )
+{
+ invalidate_user_cache();
+}
+
+$show_whats_new = false;
+
+$whats_new_major_version = get_branch_from_version(PHPWG_VERSION);
+
+if (userprefs_get_param('show_whats_new_'.$whats_new_major_version, true) and pwg_is_dbconf_writeable())
+{
+ if ($user['registration_date'] > $conf['last_major_update'])
+ {
+ userprefs_update_param('show_whats_new_'.$whats_new_major_version, false);
+ }
+ else
+ {
+ // purge old whats_new_*
+ if (isset($user['preferences']))
+ {
+ $userprefs_params_to_delete = array();
+
+ foreach (array_keys($user['preferences']) as $pref_param)
+ {
+ if (preg_match('/^whats_new_/', $pref_param))
+ {
+ $userprefs_params_to_delete[] = $pref_param;
+ }
+ }
+
+ if (count($userprefs_params_to_delete) > 0)
+ {
+ userprefs_delete_param($userprefs_params_to_delete);
+ }
+ }
+
+ $show_whats_new = true;
+ }
+}
+
+$release_note_url = PHPWG_URL.'/releases/'.$whats_new_major_version.'.0.0';
+
+$whats_new_imgs = array(
+ '1' =>'https://ressources.piwigo.com/uploads/c/v/7/cv7jpz6hf8//2025/11/12/20251112112645-7e309b67.png',
+ '2' =>'https://ressources.piwigo.com/uploads/c/v/7/cv7jpz6hf8//2025/11/12/20251112112645-61f2fcd0.png',
+ '3' =>'https://ressources.piwigo.com/uploads/c/v/7/cv7jpz6hf8//2025/11/12/20251112112646-b322153b.png',
+ // '4' =>'https://ressources.piwigo.com/uploads/c/v/7/cv7jpz6hf8//2024/11/07/20241107171642-1109101f.png',
+);
+
+//If last major update conf is less than a month old then display bell for whats new popin
+$display_bell = false;
+if (strtotime($conf['last_major_update']) > strtotime('1 month ago'))
+{
+ $display_bell = true;
+}
+
+$template->assign(
+ array(
+ 'SHOW_WHATS_NEW' => $show_whats_new,
+ 'WHATS_NEW_MAJOR_VERSION' => $whats_new_major_version,
+ 'RELEASE_NOTE_URL' => $release_note_url,
+ 'WHATS_NEW_IMGS' => $whats_new_imgs,
+ 'DISPLAY_BELL' => $display_bell,
+ )
+);
+
+// +-----------------------------------------------------------------------+
+// | Include specific page |
+// +-----------------------------------------------------------------------+
+
+trigger_notify('loc_begin_admin_page');
+include(PHPWG_ROOT_PATH.'admin/'.$page['page'].'.php');
+
+$template->assign('ACTIVE_MENU', get_active_menu($page['page']));
+
+// +-----------------------------------------------------------------------+
+// | Sending html code |
+// +-----------------------------------------------------------------------+
+
+// Add the Piwigo Official menu
+$template->assign( 'pwgmenu', pwg_URL() );
+
+include(PHPWG_ROOT_PATH.'include/page_header.php');
+
+trigger_notify('loc_end_admin');
+
+flush_page_messages();
+
+$template->pparse('admin');
+
+include(PHPWG_ROOT_PATH.'include/page_tail.php');
+
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/album.php b/Piwingo/piwigo-data/piwigo/admin/album.php
new file mode 100644
index 0000000..010c146
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/album.php
@@ -0,0 +1,85 @@
+set_id('album');
+$tabsheet->select($page['tab']);
+$tabsheet->assign();
+
+// +-----------------------------------------------------------------------+
+// | Load the tab |
+// +-----------------------------------------------------------------------+
+
+$category_name = trigger_change(
+ 'render_category_name',
+ $category['name'],
+ 'get_cat_display_name_cache'
+ );
+$template->assign(array(
+ 'ADMIN_PAGE_TITLE' => l10n('Edit album').' '.$category_name.'',
+ 'ADMIN_PAGE_OBJECT_ID' => '#'.$category['id'],
+));
+
+if ('properties' == $page['tab'])
+{
+ include(PHPWG_ROOT_PATH.'admin/cat_modify.php');
+}
+elseif ('sort_order' == $page['tab'])
+{
+ include(PHPWG_ROOT_PATH.'admin/element_set_ranks.php');
+}
+elseif ('permissions' == $page['tab'])
+{
+ $_GET['cat'] = $_GET['cat_id'];
+ include(PHPWG_ROOT_PATH.'admin/cat_perm.php');
+}
+else
+{
+ include(PHPWG_ROOT_PATH.'admin/album_'.$page['tab'].'.php');
+}
+?>
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/album_notification.php b/Piwingo/piwigo-data/piwigo/admin/album_notification.php
new file mode 100644
index 0000000..f9899f0
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/album_notification.php
@@ -0,0 +1,331 @@
+ 0)
+ {
+ $element = pwg_db_fetch_assoc($result);
+
+ $img = array(
+ 'link' => make_picture_url(
+ array(
+ 'image_id' => $element['id'],
+ 'image_file' => $element['file'],
+ 'category' => $category
+ )
+ ),
+ 'src' => DerivativeImage::url(IMG_THUMB, $element),
+ );
+ }
+ }
+
+ $args = array(
+ 'subject' => l10n('[%s] Visit album %s', $conf['gallery_title'], trigger_change('render_category_name', $category['name'], 'admin_cat_list')),
+ // TODO : change this language variable to 'Visit album %s'
+ // TODO : 'language_selected' => ....
+ );
+
+ $tpl = array(
+ 'filename' => 'cat_group_info',
+ 'assign' => array(
+ 'IMG' => $img,
+ 'CAT_NAME' => trigger_change('render_category_name', $category['name'], 'admin_cat_list'),
+ 'LINK' => make_index_url(
+ array(
+ 'category' => array(
+ 'id' => $category['id'],
+ 'name' => trigger_change('render_category_name', $category['name'], 'admin_cat_list'),
+ 'permalink' => $category['permalink']
+ )
+ )
+ ),
+ 'CPL_CONTENT' => empty($_POST['mail_content']) ? '' : stripslashes($_POST['mail_content']),
+ )
+ );
+
+ if ('users' == $_POST['who'] and isset($_POST['users']) and count($_POST['users']) > 0)
+ {
+ check_input_parameter('users', $_POST, true, PATTERN_ID);
+
+ // TODO code very similar to function pwg_mail_group. We'd better create
+ // a function pwg_mail_users that could be called from here and from
+ // pwg_mail_group
+
+ // TODO to make checks even better, we should check that theses users
+ // have access to this album. No real privacy issue here, even if we
+ // send the email to a user without permission.
+
+ $query = '
+SELECT
+ ui.user_id,
+ ui.status,
+ ui.language,
+ u.'.$conf['user_fields']['email'].' AS email,
+ u.'.$conf['user_fields']['username'].' AS username
+ FROM '.USER_INFOS_TABLE.' AS ui
+ JOIN '.USERS_TABLE.' AS u ON u.'.$conf['user_fields']['id'].' = ui.user_id
+ WHERE ui.user_id IN ('.implode(',', $_POST['users']).')
+;';
+ $users = query2array($query);
+ $usernames = array();
+
+ foreach ($users as $u)
+ {
+ $usernames[] = $u['username'];
+
+ $authkey = create_user_auth_key($u['user_id'], $u['status']);
+
+ $user_tpl = $tpl;
+
+ if ($authkey !== false)
+ {
+ $user_tpl['assign']['LINK'] = add_url_params($tpl['assign']['LINK'], array('auth' => $authkey['auth_key']));
+
+ if (isset($user_tpl['assign']['IMG']['link']))
+ {
+ $user_tpl['assign']['IMG']['link'] = add_url_params(
+ $user_tpl['assign']['IMG']['link'],
+ array('auth' => $authkey['auth_key'])
+ );
+ }
+ }
+
+ $user_args = $args;
+ if (isset($authkey['auth_key']))
+ {
+ $user_args['auth_key'] = $authkey['auth_key'];
+ }
+
+ switch_lang_to($u['language']);
+ pwg_mail($u['email'], $user_args, $user_tpl);
+ switch_lang_back();
+ }
+
+ $message = l10n_dec('%d mail was sent.', '%d mails were sent.', count($users));
+ $message.= ' ('.implode(', ', $usernames).')';
+
+ $template->assign(
+ array(
+ 'save_success' =>$message,
+ )
+ );
+ }
+ elseif ('group' == $_POST['who'] and !empty($_POST['group']))
+ {
+ check_input_parameter('group', $_POST, false, PATTERN_ID);
+
+ pwg_mail_group($_POST['group'], $args, $tpl);
+
+ $query = '
+SELECT
+ name
+ FROM `'.GROUPS_TABLE.'`
+ WHERE id = '.$_POST['group'].'
+;';
+ list($group_name) = pwg_db_fetch_row(pwg_query($query));
+
+ $template->assign(
+ array(
+ 'save_success' =>l10n('An information email was sent to group "%s"', $group_name),
+ )
+ );
+ }
+
+ unset_make_full_url();
+}
+
+// +-----------------------------------------------------------------------+
+// | template initialization |
+// +-----------------------------------------------------------------------+
+
+$template->set_filename('album_notification', 'album_notification.tpl');
+
+$template->assign(
+ array(
+ 'CATEGORIES_NAV' =>
+ trim(
+ get_cat_display_name_from_id(
+ $page['cat'],
+ 'admin.php?page=album-'
+ )
+ ),
+ 'F_ACTION' => $admin_album_base_url.'-notification',
+ 'PWG_TOKEN' => get_pwg_token(),
+ )
+ );
+
+if ($conf['auth_key_duration'] > 0)
+{
+ $template->assign(
+ 'auth_key_duration',
+ time_since(
+ strtotime('now -'.$conf['auth_key_duration'].' second'),
+ 'second',
+ null,
+ false
+ )
+ );
+}
+
+// +-----------------------------------------------------------------------+
+// | form construction |
+// +-----------------------------------------------------------------------+
+
+$query = '
+SELECT
+ id AS group_id
+ FROM `'.GROUPS_TABLE.'`
+;';
+$all_group_ids = array_from_query($query, 'group_id');
+
+if (count($all_group_ids) == 0)
+{
+ $template->assign('no_group_in_gallery', true);
+}
+else
+{
+ if ('private' == $category['status'])
+ {
+ $template->assign('permission_url', $admin_album_base_url.'-permissions');
+
+ $query = '
+SELECT
+ group_id
+ FROM '.GROUP_ACCESS_TABLE.'
+ WHERE cat_id = '.$category['id'].'
+;';
+ $group_ids = array_from_query($query, 'group_id');
+ }
+ else
+ {
+ $group_ids = $all_group_ids;
+ }
+
+ if (count($group_ids) > 0)
+ {
+ $query = '
+SELECT
+ id,
+ name
+ FROM `'.GROUPS_TABLE.'`
+ WHERE id IN ('.implode(',', $group_ids).')
+ ORDER BY name ASC
+;';
+ $template->assign(
+ 'group_mail_options',
+ simple_hash_from_query($query, 'id', 'name')
+ );
+ }
+}
+
+// all users with status != guest and permitted to this this album (for a
+// perfect search, we should also check that album is not only filled with
+// private photos)
+$query = '
+SELECT
+ user_id
+ FROM '.USER_INFOS_TABLE.'
+ WHERE status != \'guest\'
+;';
+$all_user_ids = query2array($query, null, 'user_id');
+
+if ('private' == $category['status'])
+{
+ $user_ids_access_indirect = array();
+
+ if (isset($group_ids) and count($group_ids) > 0)
+ {
+ $query = '
+SELECT
+ user_id
+ FROM '.USER_GROUP_TABLE.'
+ WHERE group_id IN ('.implode(',', $group_ids).')
+';
+ $user_ids_access_indirect = query2array($query, null, 'user_id');
+ }
+
+ $query = '
+SELECT
+ user_id
+ FROM '.USER_ACCESS_TABLE.'
+ WHERE cat_id = '.$category['id'].'
+;';
+ $user_ids_access_direct = query2array($query, null, 'user_id');
+
+ $user_ids_access = array_unique(array_merge($user_ids_access_direct, $user_ids_access_indirect));
+
+ $user_ids = array_intersect($user_ids_access, $all_user_ids);
+}
+else
+{
+ $user_ids = $all_user_ids;
+}
+
+if (count($user_ids) > 0)
+{
+ $query = '
+SELECT
+ '.$conf['user_fields']['id'].' AS id,
+ '.$conf['user_fields']['username'].' AS username
+ FROM '.USERS_TABLE.'
+ WHERE id IN ('.implode(',', $user_ids).')
+;';
+
+ $users = query2array($query, 'id', 'username');
+
+ $template->assign('user_options', $users);
+}
+
+// +-----------------------------------------------------------------------+
+// | sending html code |
+// +-----------------------------------------------------------------------+
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'album_notification');
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/albums.php b/Piwingo/piwigo-data/piwigo/admin/albums.php
new file mode 100644
index 0000000..119d71a
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/albums.php
@@ -0,0 +1,356 @@
+ $row['id'],
+ 'id_uppercat' => $row['id_uppercat'],
+ );
+ }
+
+ array_multisort(
+ $sort,
+ $order_by_field === "natural_order" ? SORT_NATURAL : SORT_REGULAR,
+ 'ASC' == $order_by_asc ? SORT_ASC : SORT_DESC,
+ $categories
+ );
+
+ save_categories_order($categories);
+
+ $open_cat = $_POST['id'];
+}
+
+$template->assign('open_cat', $open_cat);
+
+// +-----------------------------------------------------------------------+
+// | template initialization |
+// +-----------------------------------------------------------------------+
+$template->set_filename('albums', 'albums.tpl');
+
+$template->assign(
+ array(
+ 'F_ACTION' => get_root_url().'admin.php?page=albums',
+ )
+ );
+
+$template->assign('delay_before_autoOpen', $conf['album_move_delay_before_auto_opening']);
+
+$template->assign("POS_PREF", $conf['newcat_default_position']); //TODO use user pref if it exists
+
+// +-----------------------------------------------------------------------+
+// | Album display |
+// +-----------------------------------------------------------------------+
+
+//Get all albums
+$query = '
+SELECT id,name,`rank`,status, visible, uppercats, lastmodified
+ FROM '.CATEGORIES_TABLE.'
+;';
+
+$allAlbum = query2array($query);
+
+//Make an id tree
+$associatedTree = array();
+
+foreach ($allAlbum as $album)
+{
+ $album['name'] = trigger_change('render_category_name', $album['name'], 'admin_cat_list');
+ $album['lastmodified'] = time_since($album['lastmodified'], 'year');
+
+ $parents = explode(',',$album['uppercats']);
+ $the_place = &$associatedTree[strval($parents[0])];
+ for ($i=1; $i < count($parents); $i++)
+ {
+ $the_place = &$the_place['children'][strval($parents[$i])];
+ }
+ $the_place['cat'] = $album;
+}
+
+// WARNING $user['forbidden_categories'] is 100% reliable only on gallery side because
+// it's a cache variable. On administration side, if you modify public/private status
+// of an album or change permissions, this variable is reset and not recalculated until
+// you open the gallery. As this situation doesn't occur each time you use the
+// administration, it's quite reliable but not as much as on gallery side.
+$is_forbidden = array_fill_keys(@explode(',', $user['forbidden_categories']), 1);
+
+//Make an ordered tree
+function cmpCat($a, $b)
+{
+ if ($a['rank'] == $b['rank'])
+ {
+ return 0;
+ }
+ return ($a['rank'] < $b['rank']) ? -1 : 1;
+}
+
+function assocToOrderedTree($assocT)
+{
+ global $nb_photos_in, $nb_sub_photos, $is_forbidden;
+
+ $orderedTree = array();
+
+ foreach($assocT as $cat)
+ {
+ $orderedCat = array();
+ $orderedCat['rank'] = $cat['cat']['rank'];
+ $orderedCat['name'] = $cat['cat']['name'];
+ $orderedCat['status'] = $cat['cat']['status'];
+ $orderedCat['id'] = $cat['cat']['id'];
+ $orderedCat['visible'] = $cat['cat']['visible'];
+ $orderedCat['uppercats'] = $cat['cat']['uppercats'];
+ $orderedCat['nb_images'] = isset($nb_photos_in[$cat['cat']['id']]) ? $nb_photos_in[$cat['cat']['id']] : 0;
+ $orderedCat['last_updates'] = $cat['cat']['lastmodified'];
+ $orderedCat['has_not_access'] = isset($is_forbidden[$cat['cat']['id']]);
+ $orderedCat['nb_sub_photos'] = isset($nb_sub_photos[$cat['cat']['id']]) ? $nb_sub_photos[$cat['cat']['id']] : 0;
+ if (isset($cat['children']))
+ {
+ //Does not update when moving a node
+ $orderedCat['nb_subcats'] = count($cat['children']);
+ $orderedCat['children'] = assocToOrderedTree($cat['children']);
+ }
+ array_push($orderedTree, $orderedCat);
+ }
+ usort($orderedTree, 'cmpCat');
+ return $orderedTree;
+}
+
+$query = '
+SELECT
+ category_id,
+ COUNT(*) AS nb_photos
+ FROM '.IMAGE_CATEGORY_TABLE.'
+ GROUP BY category_id
+;';
+
+$nb_photos_in = query2array($query, 'category_id', 'nb_photos');
+
+$query = '
+SELECT
+ id,
+ uppercats
+ FROM '.CATEGORIES_TABLE.'
+;';
+$all_categories = query2array($query, 'id', 'uppercats');
+
+$subcats_of = array();
+
+foreach ($all_categories as $id => $uppercats)
+{
+ foreach (array_slice(explode(',', $uppercats), 0, -1) as $uppercat_id)
+ {
+ @$subcats_of[$uppercat_id][] = $id;
+ }
+}
+
+$nb_sub_photos = array();
+foreach ($subcats_of as $cat_id => $subcat_ids)
+{
+ $nb_photos = 0;
+ foreach ($subcat_ids as $id)
+ {
+ if (isset($nb_photos_in[$id]))
+ {
+ $nb_photos+= $nb_photos_in[$id];
+ }
+ }
+
+ $nb_sub_photos[$cat_id] = $nb_photos;
+}
+
+$template->assign(
+ array(
+ 'album_data' => assocToOrderedTree($associatedTree),
+ 'PWG_TOKEN' => get_pwg_token(),
+ 'nb_albums' => count($allAlbum),
+ 'ADMIN_PAGE_TITLE' => l10n('Albums'),
+ 'light_album_manager' => ($albums_counter > $conf['light_album_manager_threshold']) ? 1 : 0,
+ )
+);
+
+// +-----------------------------------------------------------------------+
+// | sending html code |
+// +-----------------------------------------------------------------------+
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'albums');
+
+// +-----------------------------------------------------------------------+
+// | functions |
+// +-----------------------------------------------------------------------+
+function get_categories_ref_date($ids, $field='date_available', $minmax='max')
+{
+ // we need to work on the whole tree under each category, even if we don't
+ // want to sort sub categories
+ $category_ids = get_subcat_ids($ids);
+
+ // search for the reference date of each album
+ $query = '
+SELECT
+ category_id,
+ '.$minmax.'('.$field.') as ref_date
+ FROM '.IMAGE_CATEGORY_TABLE.'
+ JOIN '.IMAGES_TABLE.' ON image_id = id
+ WHERE category_id IN ('.implode(',', $category_ids).')
+ GROUP BY category_id
+;';
+ $ref_dates = query2array($query, 'category_id', 'ref_date');
+
+ // the iterate on all albums (having a ref_date or not) to find the
+ // reference_date, with a search on sub-albums
+ $query = '
+SELECT
+ id,
+ uppercats
+ FROM '.CATEGORIES_TABLE.'
+ WHERE id IN ('.implode(',', $category_ids).')
+;';
+ $uppercats_of = query2array($query, 'id', 'uppercats');
+
+ foreach (array_keys($uppercats_of) as $cat_id)
+ {
+ // find the subcats
+ $subcat_ids = array();
+
+ foreach ($uppercats_of as $id => $uppercats)
+ {
+ if (preg_match('/(^|,)'.$cat_id.'(,|$)/', $uppercats))
+ {
+ $subcat_ids[] = $id;
+ }
+ }
+
+ $to_compare = array();
+ foreach ($subcat_ids as $id)
+ {
+ if (isset($ref_dates[$id]))
+ {
+ $to_compare[] = $ref_dates[$id];
+ }
+ }
+
+ if (count($to_compare) > 0)
+ {
+ $ref_dates[$cat_id] = 'max' == $minmax ? max($to_compare) : min($to_compare);
+ }
+ else
+ {
+ $ref_dates[$cat_id] = null;
+ }
+ }
+
+ // only return the list of $ids, not the sub-categories
+ $return = array();
+ foreach ($ids as $id)
+ {
+ $return[$id] = $ref_dates[$id];
+ }
+
+ return $return;
+}
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/batch_manager.php b/Piwingo/piwigo-data/piwigo/admin/batch_manager.php
new file mode 100644
index 0000000..de50e3e
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/batch_manager.php
@@ -0,0 +1,813 @@
+ 0)
+ {
+ $_SESSION['page_infos'][] = l10n_dec(
+ '%d photo was deleted', '%d photos were deleted',
+ $_GET['nb_orphans_deleted']
+ );
+
+ redirect(get_root_url().'admin.php?page='.$_GET['page']);
+ }
+ }
+
+ if ('sync_md5sum' == $_GET['action'] and isset($_GET['nb_md5sum_added']))
+ {
+ check_input_parameter('nb_md5sum_added', $_GET, false, '/^\d+$/');
+ if ($_GET['nb_md5sum_added'] > 0)
+ {
+ $_SESSION['page_infos'][] = l10n_dec(
+ '%d checksums were added', '%d checksums were added',
+ $_GET['nb_md5sum_added']
+ );
+
+ redirect(get_root_url().'admin.php?page='.$_GET['page']);
+ }
+ }
+}
+// +-----------------------------------------------------------------------+
+// | initialize current set |
+// +-----------------------------------------------------------------------+
+
+// filters from form
+if (isset($_POST['submitFilter']))
+{
+ // echo ''; print_r($_POST); echo '
';
+ unset($_REQUEST['start']); // new photo set must reset the page
+ $_SESSION['bulk_manager_filter'] = array();
+
+ if (isset($_POST['filter_prefilter_use']))
+ {
+ $_SESSION['bulk_manager_filter']['prefilter'] = $_POST['filter_prefilter'];
+
+ if ('duplicates' == $_POST['filter_prefilter'])
+ {
+ $has_options = false;
+
+ if (isset($_POST['filter_duplicates_checksum']))
+ {
+ $_SESSION['bulk_manager_filter']['duplicates_checksum'] = true;
+ $has_options = true;
+ }
+
+ if (isset($_POST['filter_duplicates_date']))
+ {
+ $_SESSION['bulk_manager_filter']['duplicates_date'] = true;
+ $has_options = true;
+ }
+
+ if (isset($_POST['filter_duplicates_dimensions']))
+ {
+ $_SESSION['bulk_manager_filter']['duplicates_dimensions'] = true;
+ $has_options = true;
+ }
+
+ if (!$has_options or isset($_POST['filter_duplicates_filename']))
+ {
+ $_SESSION['bulk_manager_filter']['duplicates_filename'] = true;
+ }
+ }
+ }
+
+ if (isset($_POST['filter_category_use']))
+ {
+ check_input_parameter('filter_category', $_POST, false, PATTERN_ID);
+
+ $_SESSION['bulk_manager_filter']['category'] = $_POST['filter_category'];
+
+ if (isset($_POST['filter_category_recursive']))
+ {
+ $_SESSION['bulk_manager_filter']['category_recursive'] = true;
+ }
+ }
+
+ if (isset($_POST['filter_tags_use']))
+ {
+ $_SESSION['bulk_manager_filter']['tags'] = get_tag_ids($_POST['filter_tags'], false);
+
+ if (isset($_POST['tag_mode']) and in_array($_POST['tag_mode'], array('AND', 'OR')))
+ {
+ $_SESSION['bulk_manager_filter']['tag_mode'] = $_POST['tag_mode'];
+ }
+ }
+
+ if (isset($_POST['filter_level_use']))
+ {
+ check_input_parameter('filter_level', $_POST, false, '/^\d+$/');
+
+ if (in_array($_POST['filter_level'], $conf['available_permission_levels']))
+ {
+ $_SESSION['bulk_manager_filter']['level'] = $_POST['filter_level'];
+
+ if (isset($_POST['filter_level_include_lower']))
+ {
+ $_SESSION['bulk_manager_filter']['level_include_lower'] = true;
+ }
+ }
+ }
+
+ if (isset($_POST['filter_dimension_use']))
+ {
+ foreach (array('min_width','max_width','min_height','max_height') as $type)
+ {
+ if (filter_var($_POST['filter_dimension_'.$type], FILTER_VALIDATE_INT) !== false)
+ {
+ $_SESSION['bulk_manager_filter']['dimension'][$type] = $_POST['filter_dimension_'. $type ];
+ }
+ }
+ foreach (array('min_ratio','max_ratio') as $type)
+ {
+ if (filter_var($_POST['filter_dimension_'.$type], FILTER_VALIDATE_FLOAT) !== false)
+ {
+ $_SESSION['bulk_manager_filter']['dimension'][$type] = $_POST['filter_dimension_'. $type ];
+ }
+ }
+ }
+
+ if (isset($_POST['filter_filesize_use']))
+ {
+ foreach (array('min','max') as $type)
+ {
+ if (filter_var($_POST['filter_filesize_'.$type], FILTER_VALIDATE_FLOAT) !== false)
+ {
+ $_SESSION['bulk_manager_filter']['filesize'][$type] = $_POST['filter_filesize_'. $type ];
+ }
+ }
+ }
+
+ if (isset($_POST['filter_search_use']))
+ {
+ $_SESSION['bulk_manager_filter']['search']['q'] = $_POST['q'];
+ }
+
+ $_SESSION['bulk_manager_filter'] = trigger_change('batch_manager_register_filters', $_SESSION['bulk_manager_filter']);
+}
+// filters from url
+elseif (isset($_GET['filter']))
+{
+ if (!is_array($_GET['filter']))
+ {
+ $_GET['filter'] = explode(',', $_GET['filter']);
+ }
+
+ $_SESSION['bulk_manager_filter'] = array();
+
+ foreach ($_GET['filter'] as $filter)
+ {
+ list($type, $value) = explode('-', $filter, 2);
+
+ switch ($type)
+ {
+ case 'prefilter':
+ if (preg_match('/^duplicates-?/', $value))
+ {
+ list(, $duplicate_field) = explode('-', $value, 2);
+ $_SESSION['bulk_manager_filter']['prefilter'] = 'duplicates';
+
+ if (in_array($duplicate_field, array('filename', 'checksum', 'date', 'dimensions')))
+ {
+ $_SESSION['bulk_manager_filter']['duplicates_'.$duplicate_field] = true;
+ }
+ }
+ else
+ {
+ $_SESSION['bulk_manager_filter']['prefilter'] = $value;
+ }
+ break;
+
+ case 'album': case 'category': case 'cat':
+ if (is_numeric($value))
+ {
+ $_SESSION['bulk_manager_filter']['category'] = $value;
+ }
+ break;
+
+ case 'tag':
+ if (is_numeric($value))
+ {
+ $_SESSION['bulk_manager_filter']['tags'] = array($value);
+ $_SESSION['bulk_manager_filter']['tag_mode'] = 'AND';
+ }
+ break;
+
+ case 'level':
+ if (is_numeric($value) && in_array($value, $conf['available_permission_levels']))
+ {
+ $_SESSION['bulk_manager_filter']['level'] = $value;
+ }
+ break;
+
+ case 'search':
+ $_SESSION['bulk_manager_filter']['search']['q'] = $value;
+ break;
+
+ case 'dimension':
+ $dim_map = array('w'=>'width','h'=>'height','r'=>'ratio');
+ foreach (explode('-', $value) as $part)
+ {
+ $values = explode('..', substr($part, 1));
+ if (isset($dim_map[$part[0]]))
+ {
+ $type = $dim_map[$part[0]];
+ list(
+ $_SESSION['bulk_manager_filter']['dimension']['min_'.$type],
+ $_SESSION['bulk_manager_filter']['dimension']['max_'.$type]
+ ) = $values;
+ }
+ }
+ break;
+
+ case 'filesize':
+ list(
+ $_SESSION['bulk_manager_filter']['filesize']['min'],
+ $_SESSION['bulk_manager_filter']['filesize']['max']
+ ) = explode('..', $value);
+ break;
+
+ default:
+ $_SESSION['bulk_manager_filter'] = trigger_change('batch_manager_url_filter', $_SESSION['bulk_manager_filter'], $filter);
+ break;
+ }
+ }
+}
+
+if (empty($_SESSION['bulk_manager_filter']))
+{
+ $_SESSION['bulk_manager_filter'] = array(
+ 'prefilter' => 'caddie'
+ );
+}
+
+// echo ''; print_r($_SESSION['bulk_manager_filter']); echo '
';
+
+// depending on the current filter (in session), we find the appropriate photos
+$filter_sets = array();
+if (isset($_SESSION['bulk_manager_filter']['prefilter']))
+{
+ switch ($_SESSION['bulk_manager_filter']['prefilter'])
+ {
+ case 'caddie':
+ $query = '
+SELECT element_id
+ FROM '.CADDIE_TABLE.'
+ WHERE user_id = '.$user['id'].'
+;';
+ $filter_sets[] = query2array($query, null, 'element_id');
+
+ break;
+
+ case 'favorites':
+ $query = '
+SELECT image_id
+ FROM '.FAVORITES_TABLE.'
+ WHERE user_id = '.$user['id'].'
+;';
+ $filter_sets[] = query2array($query, null, 'image_id');
+
+ break;
+
+ case 'last_import':
+ $query = '
+SELECT MAX(date_available) AS date
+ FROM '.IMAGES_TABLE.'
+;';
+ $row = pwg_db_fetch_assoc(pwg_query($query));
+ if (!empty($row['date']))
+ {
+ $query = '
+SELECT id
+ FROM '.IMAGES_TABLE.'
+ WHERE date_available BETWEEN '.pwg_db_get_recent_period_expression(1, $row['date']).' AND \''.$row['date'].'\'
+;';
+ $filter_sets[] = query2array($query, null, 'id');
+ }
+
+ break;
+
+ case 'no_virtual_album':
+ // we are searching elements not linked to any virtual category
+ $query = '
+ SELECT id
+ FROM '.IMAGES_TABLE.'
+ ;';
+ $all_elements = query2array($query, null, 'id');
+
+ $linked_to_virtual = array();
+
+ $query = '
+ SELECT id
+ FROM '.CATEGORIES_TABLE.'
+ WHERE dir IS NULL
+ ;';
+ $virtual_categories = query2array($query, null, 'id');
+ if (!empty($virtual_categories))
+ {
+ $query = '
+ SELECT DISTINCT(image_id)
+ FROM '.IMAGE_CATEGORY_TABLE.'
+ WHERE category_id IN ('.implode(',', $virtual_categories).')
+ ;';
+ $linked_to_virtual = query2array($query, null, 'image_id');
+ }
+
+ $filter_sets[] = array_diff($all_elements, $linked_to_virtual);
+
+ break;
+
+ case 'no_album':
+ $filter_sets[] = get_orphans();
+ break;
+ case 'no_sync_md5sum':
+ $filter_sets[] = get_photos_no_md5sum();
+ break;
+
+ case 'no_tag':
+ $query = '
+SELECT
+ id
+ FROM '.IMAGES_TABLE.'
+ LEFT JOIN '.IMAGE_TAG_TABLE.' ON id = image_id
+ WHERE tag_id is null
+;';
+ $filter_sets[] = query2array($query, null, 'id');
+
+ break;
+
+
+ case 'duplicates':
+ $duplicates_on_fields = array();
+
+ if (isset($_SESSION['bulk_manager_filter']['duplicates_filename']))
+ {
+ $duplicates_on_fields[] = 'file';
+ }
+
+ if (isset($_SESSION['bulk_manager_filter']['duplicates_checksum']))
+ {
+ $duplicates_on_fields[] = 'md5sum';
+ }
+
+ if (isset($_SESSION['bulk_manager_filter']['duplicates_date']))
+ {
+ $duplicates_on_fields[] = 'date_creation';
+ }
+
+ if (isset($_SESSION['bulk_manager_filter']['duplicates_dimensions']))
+ {
+ $duplicates_on_fields[] = 'width';
+ $duplicates_on_fields[] = 'height';
+ }
+
+ // TODO improve this algorithm, because GROUP_CONCAT is truncated at
+ // 1024 chars. So if you have more than ~250 duplicates for a given
+ // combination of "duplicates_on_fields" you won't get all the
+ // duplicates.
+
+ $query = '
+SELECT
+ GROUP_CONCAT(id) AS ids
+ FROM '.IMAGES_TABLE;
+
+ if (in_array('md5sum', $duplicates_on_fields))
+ {
+ $query.= '
+ WHERE md5sum IS NOT NULL
+';
+ }
+
+ $query.= '
+ GROUP BY '.implode(',', $duplicates_on_fields).'
+ HAVING COUNT(*) > 1
+;';
+ $array_of_ids_string = query2array($query, null, 'ids');
+
+ $ids = array();
+
+ foreach ($array_of_ids_string as $ids_string)
+ {
+ $ids_string = rtrim($ids_string,',');
+ $ids = array_merge($ids, explode(',', $ids_string));
+ }
+
+ $filter_sets[] = $ids;
+
+ break;
+
+ case 'all_photos':
+ if ( count($_SESSION['bulk_manager_filter']) == 1 )
+ {// make the query only if this is the only filter
+ $query = '
+SELECT id
+ FROM '.IMAGES_TABLE.'
+ '.$conf['order_by'];
+
+ $filter_sets[] = query2array($query, null, 'id');
+ }
+ break;
+
+ default:
+ $filter_sets = trigger_change('perform_batch_manager_prefilters', $filter_sets, $_SESSION['bulk_manager_filter']['prefilter']);
+ break;
+ }
+}
+
+if (isset($_SESSION['bulk_manager_filter']['category']))
+{
+ $categories = array();
+
+ // we need to check the category still exists (it may have been deleted since it was added in the session)
+ $query = '
+SELECT COUNT(*)
+ FROM '.CATEGORIES_TABLE.'
+ WHERE id = '.$_SESSION['bulk_manager_filter']['category'].'
+;';
+ list($counter) = pwg_db_fetch_row(pwg_query($query));
+ if (0 == $counter)
+ {
+ unset($_SESSION['bulk_manager_filter']);
+ redirect(get_root_url().'admin.php?page='.$_GET['page']);
+ }
+
+ if (isset($_SESSION['bulk_manager_filter']['category_recursive']))
+ {
+ $categories = get_subcat_ids(array($_SESSION['bulk_manager_filter']['category']));
+ }
+ else
+ {
+ $categories = array($_SESSION['bulk_manager_filter']['category']);
+ }
+
+ $query = '
+ SELECT DISTINCT(image_id)
+ FROM '.IMAGE_CATEGORY_TABLE.'
+ WHERE category_id IN ('.implode(',', $categories).')
+ ;';
+ $filter_sets[] = query2array($query, null, 'image_id');
+}
+
+if (isset($_SESSION['bulk_manager_filter']['level']))
+{
+ $operator = '=';
+ if (isset($_SESSION['bulk_manager_filter']['level_include_lower']))
+ {
+ $operator = '<=';
+ }
+
+ $query = '
+SELECT id
+ FROM '.IMAGES_TABLE.'
+ WHERE level '.$operator.' '.$_SESSION['bulk_manager_filter']['level'].'
+ '.$conf['order_by'];
+
+ $filter_sets[] = query2array($query, null, 'id');
+}
+
+if (!empty($_SESSION['bulk_manager_filter']['tags']))
+{
+ $filter_sets[] = get_image_ids_for_tags(
+ $_SESSION['bulk_manager_filter']['tags'],
+ $_SESSION['bulk_manager_filter']['tag_mode'],
+ null,
+ null,
+ false // we don't apply permissions in administration screens
+ );
+}
+
+if (isset($_SESSION['bulk_manager_filter']['dimension']))
+{
+ $where_clauses = array();
+ if (isset($_SESSION['bulk_manager_filter']['dimension']['min_width']))
+ {
+ $where_clause[] = 'width >= '.$_SESSION['bulk_manager_filter']['dimension']['min_width'];
+ }
+ if (isset($_SESSION['bulk_manager_filter']['dimension']['max_width']))
+ {
+ $where_clause[] = 'width <= '.$_SESSION['bulk_manager_filter']['dimension']['max_width'];
+ }
+ if (isset($_SESSION['bulk_manager_filter']['dimension']['min_height']))
+ {
+ $where_clause[] = 'height >= '.$_SESSION['bulk_manager_filter']['dimension']['min_height'];
+ }
+ if (isset($_SESSION['bulk_manager_filter']['dimension']['max_height']))
+ {
+ $where_clause[] = 'height <= '.$_SESSION['bulk_manager_filter']['dimension']['max_height'];
+ }
+ if (isset($_SESSION['bulk_manager_filter']['dimension']['min_ratio']))
+ {
+ $where_clause[] = 'width/height >= '.$_SESSION['bulk_manager_filter']['dimension']['min_ratio'];
+ }
+ if (isset($_SESSION['bulk_manager_filter']['dimension']['max_ratio']))
+ {
+ // max_ratio is a floor value, so must be a bit increased
+ $where_clause[] = 'width/height < '.($_SESSION['bulk_manager_filter']['dimension']['max_ratio']+0.01);
+ }
+
+ $query = '
+SELECT id
+ FROM '.IMAGES_TABLE.'
+ WHERE '.implode(' AND ',$where_clause).'
+ '.$conf['order_by'];
+
+ $filter_sets[] = query2array($query, null, 'id');
+}
+
+if (isset($_SESSION['bulk_manager_filter']['filesize']))
+{
+ $where_clauses = array();
+
+ if (isset($_SESSION['bulk_manager_filter']['filesize']['min']))
+ {
+ // to counter the effect of converting kB to mB and rounding, we need to go slightly lower for the minimum value
+ $where_clause[] = 'filesize >= '.($_SESSION['bulk_manager_filter']['filesize']['min'] - 0.1)*1024;
+ }
+
+ if (isset($_SESSION['bulk_manager_filter']['filesize']['max']))
+ {
+ // to counter the effect of converting kB to mB and rounding, we need to go slightly higher for the maximum value
+ $where_clause[] = 'filesize <= '.($_SESSION['bulk_manager_filter']['filesize']['max'] + 0.1)*1024;
+ }
+
+ $query = '
+SELECT id
+ FROM '.IMAGES_TABLE.'
+ WHERE '.implode(' AND ',$where_clause).'
+ '.$conf['order_by'];
+
+ $filter_sets[] = query2array($query, null, 'id');
+}
+
+if (isset($_SESSION['bulk_manager_filter']['search']) &&
+ strlen($_SESSION['bulk_manager_filter']['search']['q']))
+{
+ include_once( PHPWG_ROOT_PATH .'include/functions_search.inc.php' );
+ $res = get_quick_search_results_no_cache($_SESSION['bulk_manager_filter']['search']['q'], array('permissions'=>false));
+ if (!empty($res['items']) && !empty($res['qs']['unmatched_terms']))
+ {
+ $template->assign('no_search_results', array_map('htmlspecialchars', $res['qs']['unmatched_terms']) );
+ }
+ $filter_sets[] = $res['items'];
+}
+
+$filter_sets = trigger_change('batch_manager_perform_filters', $filter_sets, $_SESSION['bulk_manager_filter']);
+
+$current_set = array_shift($filter_sets);
+foreach ($filter_sets as $set)
+{
+ $current_set = array_intersect($current_set, $set);
+}
+$page['cat_elements_id'] = empty($current_set) ? array() : $current_set;
+
+
+// +-----------------------------------------------------------------------+
+// | first element to display |
+// +-----------------------------------------------------------------------+
+
+// $page['start'] contains the number of the first element in its
+// category. For exampe, $page['start'] = 12 means we must show elements #12
+// and $page['nb_images'] next elements
+
+if (!isset($_REQUEST['start'])
+ or !is_numeric($_REQUEST['start'])
+ or $_REQUEST['start'] < 0
+ or (isset($_REQUEST['display']) and 'all' == $_REQUEST['display']))
+{
+ $page['start'] = 0;
+}
+else
+{
+ $page['start'] = $_REQUEST['start'];
+}
+
+
+// +-----------------------------------------------------------------------+
+// | Tabs |
+// +-----------------------------------------------------------------------+
+$manager_link = get_root_url().'admin.php?page=batch_manager&mode=';
+
+if (isset($_GET['mode']))
+{
+ check_input_parameter('mode', $_GET, false, '/^(global|unit)$/');
+ $page['tab'] = $_GET['mode'];
+}
+else
+{
+ $page['tab'] = 'global';
+}
+
+$tabsheet = new tabsheet();
+$tabsheet->set_id('batch_manager');
+$tabsheet->select($page['tab']);
+$tabsheet->assign();
+
+
+// +-----------------------------------------------------------------------+
+// | dimensions |
+// +-----------------------------------------------------------------------+
+
+$widths = array();
+$heights = array();
+$ratios = array();
+$dimensions = array();
+
+// get all width, height and ratios
+$query = '
+SELECT
+ DISTINCT width, height
+ FROM '.IMAGES_TABLE.'
+ WHERE width IS NOT NULL
+ AND height IS NOT NULL
+;';
+$result = pwg_query($query);
+
+if (pwg_db_num_rows($result))
+{
+ while ($row = pwg_db_fetch_assoc($result))
+ {
+ if ($row['width']>0 && $row['height']>0)
+ {
+ $widths[] = $row['width'];
+ $heights[] = $row['height'];
+ $ratios[] = floor($row['width'] / $row['height'] * 100) / 100;
+ }
+ }
+}
+if (empty($widths))
+{ // arbitrary values, only used when no photos on the gallery
+ $widths = array(600, 1920, 3500);
+ $heights = array(480, 1080, 2300);
+ $ratios = array(1.25, 1.52, 1.78);
+}
+
+foreach (array('widths','heights','ratios') as $type)
+{
+ ${$type} = array_unique(${$type});
+ sort(${$type});
+ $dimensions[$type] = implode(',', ${$type});
+}
+
+$dimensions['bounds'] = array(
+ 'min_width' => $widths[0],
+ 'max_width' => end($widths),
+ 'min_height' => $heights[0],
+ 'max_height' => end($heights),
+ 'min_ratio' => $ratios[0],
+ 'max_ratio' => end($ratios),
+ );
+
+// find ratio categories
+$ratio_categories = array(
+ 'portrait' => array(),
+ 'square' => array(),
+ 'landscape' => array(),
+ 'panorama' => array(),
+ );
+
+foreach ($ratios as $ratio)
+{
+ if ($ratio < 0.95)
+ {
+ $ratio_categories['portrait'][] = $ratio;
+ }
+ else if ($ratio >= 0.95 and $ratio <= 1.05)
+ {
+ $ratio_categories['square'][] = $ratio;
+ }
+ else if ($ratio > 1.05 and $ratio < 2)
+ {
+ $ratio_categories['landscape'][] = $ratio;
+ }
+ else if ($ratio >= 2)
+ {
+ $ratio_categories['panorama'][] = $ratio;
+ }
+}
+
+foreach (array_keys($ratio_categories) as $type)
+{
+ if (count($ratio_categories[$type]) > 0)
+ {
+ $dimensions['ratio_'.$type] = array(
+ 'min' => $ratio_categories[$type][0],
+ 'max' => end($ratio_categories[$type]),
+ );
+ }
+}
+
+// selected=bound if nothing selected
+foreach (array_keys($dimensions['bounds']) as $type)
+{
+ $dimensions['selected'][$type] = isset($_SESSION['bulk_manager_filter']['dimension'][$type])
+ ? $_SESSION['bulk_manager_filter']['dimension'][$type]
+ : $dimensions['bounds'][$type]
+ ;
+}
+
+$template->assign('dimensions', $dimensions);
+
+// +-----------------------------------------------------------------------+
+// | filesize |
+// +-----------------------------------------------------------------------+
+
+$filesizes = array();
+$filesize = array();
+
+$query = '
+SELECT
+ filesize
+ FROM '.IMAGES_TABLE.'
+ WHERE filesize IS NOT NULL
+ GROUP BY filesize
+;';
+$result = pwg_query($query);
+
+while ($row = pwg_db_fetch_assoc($result))
+{
+ $filesizes[] = sprintf('%.1f', $row['filesize']/1024);
+}
+
+if (empty($filesizes))
+{ // arbitrary values, only used when no photos on the gallery
+ $filesizes = array(0, 1, 2, 5, 8, 15);
+}
+
+$filesizes = array_unique($filesizes);
+sort($filesizes);
+
+$filesize['list'] = implode(',', $filesizes);
+
+$filesize['bounds'] = array(
+ 'min' => $filesizes[0],
+ 'max' => end($filesizes),
+ );
+
+// selected=bound if nothing selected
+foreach (array_keys($filesize['bounds']) as $type)
+{
+ $filesize['selected'][$type] = isset($_SESSION['bulk_manager_filter']['filesize'][$type])
+ ? $_SESSION['bulk_manager_filter']['filesize'][$type]
+ : $filesize['bounds'][$type]
+ ;
+}
+
+$template->assign('filesize', $filesize);
+
+// +-----------------------------------------------------------------------+
+// | open specific mode |
+// +-----------------------------------------------------------------------+
+
+include(PHPWG_ROOT_PATH.'admin/batch_manager_'.$page['tab'].'.php');
+?>
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/batch_manager_global.php b/Piwingo/piwigo-data/piwigo/admin/batch_manager_global.php
new file mode 100644
index 0000000..8e7e968
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/batch_manager_global.php
@@ -0,0 +1,621 @@
+ 0)
+ {
+ $taglist_before = get_image_tag_ids($collection);
+
+ $query = '
+DELETE
+ FROM '.IMAGE_TAG_TABLE.'
+ WHERE image_id IN ('.implode(',', $collection).')
+ AND tag_id IN ('.implode(',', $_POST['del_tags']).')
+;';
+ pwg_query($query);
+
+ $taglist_after = get_image_tag_ids($collection);
+ $images_to_update = compare_image_tag_lists($taglist_before, $taglist_after);
+ update_images_lastmodified($images_to_update);
+
+ if (isset($_SESSION['bulk_manager_filter']['tags']) &&
+ count(array_intersect($_SESSION['bulk_manager_filter']['tags'], $_POST['del_tags'])))
+ {
+ $redirect = true;
+ }
+ }
+ else
+ {
+ $page['errors'][] = l10n('Select at least one tag');
+ }
+ }
+
+ if ('associate' == $action)
+ {
+ if (empty($_POST['associate']))
+ {
+ $page['errors'][] = l10n('Select at least one album');
+ } else {
+ associate_images_to_categories(
+ $collection,
+ $_POST['associate']
+ );
+
+ $_SESSION['page_infos'] = array(
+ l10n('Information data registered in database')
+ );
+
+ // let's refresh the page because we the current set might be modified
+ if ('no_album' == $page['prefilter'])
+ {
+ $redirect = true;
+ }
+
+ else if ('no_virtual_album' == $page['prefilter'])
+ {
+ $category_info = get_cat_info($_POST['associate']);
+ if (empty($category_info['dir']))
+ {
+ $redirect = true;
+ }
+ }
+ }
+ }
+
+ else if ('move' == $action)
+ {
+ move_images_to_categories($collection, array($_POST['move']));
+
+ $_SESSION['page_infos'] = array(
+ l10n('Information data registered in database')
+ );
+
+ // let's refresh the page because we the current set might be modified
+ if ('no_album' == $page['prefilter'])
+ {
+ $redirect = true;
+ }
+
+ else if ('no_virtual_album' == $page['prefilter'])
+ {
+ $category_info = get_cat_info($_POST['move']);
+ if (empty($category_info['dir']))
+ {
+ $redirect = true;
+ }
+ }
+
+ else if (isset($_SESSION['bulk_manager_filter']['category'])
+ and $_POST['move'] != $_SESSION['bulk_manager_filter']['category'])
+ {
+ $redirect = true;
+ }
+ }
+
+ else if ('dissociate' == $action)
+ {
+ $nb_dissociated = dissociate_images_from_category($collection, $_POST['dissociate']);
+
+ if ($nb_dissociated > 0)
+ {
+ $_SESSION['page_infos'] = array(
+ l10n('Information data registered in database')
+ );
+
+ // let's refresh the page because the current set might be modified
+ $redirect = true;
+ }
+ }
+
+ // author
+ else if ('author' == $action)
+ {
+ if (isset($_POST['remove_author']))
+ {
+ $_POST['author'] = null;
+ }
+
+ $datas = array();
+ foreach ($collection as $image_id)
+ {
+ $datas[] = array(
+ 'id' => $image_id,
+ 'author' => $_POST['author']
+ );
+ }
+
+ mass_updates(
+ IMAGES_TABLE,
+ array('primary' => array('id'), 'update' => array('author')),
+ $datas
+ );
+
+ pwg_activity('photo', $collection, 'edit', array('action'=>'author'));
+ }
+
+ // title
+ else if ('title' == $action)
+ {
+ if (isset($_POST['remove_title']))
+ {
+ $_POST['title'] = null;
+ }
+
+ $datas = array();
+ foreach ($collection as $image_id)
+ {
+ $datas[] = array(
+ 'id' => $image_id,
+ 'name' => $_POST['title']
+ );
+ }
+
+ mass_updates(
+ IMAGES_TABLE,
+ array('primary' => array('id'), 'update' => array('name')),
+ $datas
+ );
+
+ pwg_activity('photo', $collection, 'edit', array('action'=>'title'));
+ }
+
+ // date_creation
+ else if ('date_creation' == $action)
+ {
+ if (isset($_POST['remove_date_creation']) || empty($_POST['date_creation']))
+ {
+ $date_creation = null;
+ }
+ else
+ {
+ $date_creation = $_POST['date_creation'];
+ }
+
+ $datas = array();
+ foreach ($collection as $image_id)
+ {
+ $datas[] = array(
+ 'id' => $image_id,
+ 'date_creation' => $date_creation
+ );
+ }
+
+ mass_updates(
+ IMAGES_TABLE,
+ array('primary' => array('id'), 'update' => array('date_creation')),
+ $datas
+ );
+
+ pwg_activity('photo', $collection, 'edit', array('action'=>'date_creation'));
+ }
+
+ // privacy_level
+ else if ('level' == $action)
+ {
+ $datas = array();
+ foreach ($collection as $image_id)
+ {
+ $datas[] = array(
+ 'id' => $image_id,
+ 'level' => $_POST['level']
+ );
+ }
+
+ mass_updates(
+ IMAGES_TABLE,
+ array('primary' => array('id'), 'update' => array('level')),
+ $datas
+ );
+
+ pwg_activity('photo', $collection, 'edit', array('action'=>'privacy_level'));
+
+ if (isset($_SESSION['bulk_manager_filter']['level']))
+ {
+ if ($_POST['level'] < $_SESSION['bulk_manager_filter']['level'])
+ {
+ $redirect = true;
+ }
+ }
+ }
+
+ // add_to_caddie
+ else if ('add_to_caddie' == $action)
+ {
+ fill_caddie($collection);
+ }
+
+ // delete
+ else if ('delete' == $action)
+ {
+ if (isset($_POST['confirm_deletion']) and 1 == $_POST['confirm_deletion'])
+ {
+ // now done with ajax calls, with blocks
+ // $deleted_count = delete_elements($collection, true);
+ if (count($collection) > 0)
+ {
+ $_SESSION['page_infos'][] = l10n_dec(
+ '%d photo was deleted', '%d photos were deleted',
+ count($collection)
+ );
+
+ $redirect_url = get_root_url().'admin.php?page='.$_GET['page'];
+ $redirect = true;
+ }
+ else
+ {
+ $page['errors'][] = l10n('No photo can be deleted');
+ }
+ }
+ else
+ {
+ $page['errors'][] = l10n('You need to confirm deletion');
+ }
+ }
+
+ // synchronize metadata
+ else if ('metadata' == $action)
+ {
+ $page['infos'][] = l10n('Metadata synchronized from file').' '.count($collection).'';
+ }
+
+ else if ('delete_derivatives' == $action && !empty($_POST['del_derivatives_type']))
+ {
+ $query='SELECT path,representative_ext FROM '.IMAGES_TABLE.'
+ WHERE id IN ('.implode(',', $collection).')';
+ $result = pwg_query($query);
+ while ($info = pwg_db_fetch_assoc($result))
+ {
+ foreach( $_POST['del_derivatives_type'] as $type)
+ {
+ delete_element_derivatives($info, $type);
+ }
+ }
+ }
+
+ else if ('generate_derivatives' == $action)
+ {
+ if ($_POST['regenerateSuccess'] != '0')
+ {
+ $page['infos'][] = l10n('%s photos have been regenerated', $_POST['regenerateSuccess']);
+ }
+ if ($_POST['regenerateError'] != '0')
+ {
+ $page['warnings'][] = l10n('%s photos can not be regenerated', $_POST['regenerateError']);
+ }
+ }
+
+ if (!in_array($action, array('remove_from_caddie','add_to_caddie','delete_derivatives','generate_derivatives')))
+ {
+ invalidate_user_cache();
+ }
+
+ trigger_notify('element_set_global_action', $action, $collection);
+
+ if ($redirect)
+ {
+ redirect($redirect_url);
+ }
+}
+
+// +-----------------------------------------------------------------------+
+// | template init |
+// +-----------------------------------------------------------------------+
+$template->set_filenames(array('batch_manager_global' => 'batch_manager_global.tpl'));
+
+$base_url = get_root_url().'admin.php';
+
+include(PHPWG_ROOT_PATH.'admin/include/batch_manager_filters.inc.php');
+
+// +-----------------------------------------------------------------------+
+// | caddie options |
+// +-----------------------------------------------------------------------+
+$template->assign('IN_CADDIE', 'caddie' == $page['prefilter']);
+
+// +-----------------------------------------------------------------------+
+// | global mode form |
+// +-----------------------------------------------------------------------+
+
+if (count($page['cat_elements_id']) > 0)
+{
+ // remove tags
+ $template->assign('associated_tags', get_common_tags($page['cat_elements_id'], -1));
+}
+
+// creation date
+$template->assign('DATE_CREATION',
+ empty($_POST['date_creation']) ? date('Y-m-d').' 00:00:00' : $_POST['date_creation']
+ );
+
+// image level options
+$template->assign(
+ array(
+ 'level_options'=> get_privacy_level_options(),
+ 'level_options_selected' => 0,
+ )
+ );
+
+// metadata
+include_once( PHPWG_ROOT_PATH.'admin/site_reader_local.php');
+$site_reader = new LocalSiteReader('./');
+$used_metadata = implode( ', ', $site_reader->get_metadata_attributes());
+
+$template->assign(
+ array(
+ 'used_metadata' => $used_metadata,
+ )
+ );
+
+//derivatives
+$del_deriv_map = array();
+foreach(ImageStdParams::get_defined_type_map() as $params)
+{
+ $del_deriv_map[$params->type] = l10n($params->type);
+}
+$gen_deriv_map = $del_deriv_map;
+$del_deriv_map[IMG_CUSTOM] = l10n(IMG_CUSTOM);
+$template->assign(
+ array(
+ 'del_derivatives_types' => $del_deriv_map,
+ 'generate_derivatives_types' => $gen_deriv_map,
+ )
+ );
+
+// +-----------------------------------------------------------------------+
+// | global mode thumbnails |
+// +-----------------------------------------------------------------------+
+
+// how many items to display on this page
+if (!empty($_GET['display']))
+{
+ if ('all' == $_GET['display'])
+ {
+ $page['nb_images'] = count($page['cat_elements_id']);
+ }
+ else
+ {
+ $page['nb_images'] = intval($_GET['display']);
+ }
+}
+elseif (in_array($conf['batch_manager_images_per_page_global'], array(20, 50, 100)))
+{
+ $page['nb_images'] = $conf['batch_manager_images_per_page_global'];
+}
+else
+{
+ $page['nb_images'] = 20;
+}
+
+$nb_thumbs_page = 0;
+
+if (count($page['cat_elements_id']) > 0)
+{
+ $nav_bar = create_navigation_bar(
+ $base_url.get_query_string_diff(array('start')),
+ count($page['cat_elements_id']),
+ $page['start'],
+ $page['nb_images']
+ );
+ $template->assign('navbar', $nav_bar);
+
+ $is_category = false;
+ if (isset($_SESSION['bulk_manager_filter']['category'])
+ and !isset($_SESSION['bulk_manager_filter']['category_recursive']))
+ {
+ $is_category = true;
+ }
+
+ // If using the 'duplicates' filter,
+ // order by the fields that are used to find duplicates.
+ if (isset($_SESSION['bulk_manager_filter']['prefilter'])
+ and 'duplicates' === $_SESSION['bulk_manager_filter']['prefilter']
+ and isset($duplicates_on_fields))
+ {
+ // The $duplicates_on_fields variable is defined in ./batch_manager.php
+ $order_by_fields = array_merge( $duplicates_on_fields, array( 'id' ) );
+ $conf['order_by'] = ' ORDER BY '.join(', ', $order_by_fields);
+ }
+
+ $query = '
+SELECT id,path,representative_ext,file,filesize,level,name,width,height,rotation
+ FROM '.IMAGES_TABLE;
+
+ if ($is_category)
+ {
+ $category_info = get_cat_info($_SESSION['bulk_manager_filter']['category']);
+
+ $conf['order_by'] = $conf['order_by_inside_category'];
+ if (!empty($category_info['image_order']))
+ {
+ $conf['order_by'] = ' ORDER BY '.$category_info['image_order'];
+ }
+
+ $query.= '
+ JOIN '.IMAGE_CATEGORY_TABLE.' ON id = image_id';
+ }
+
+ $query.= '
+ WHERE id IN ('.implode(',', $page['cat_elements_id']).')';
+
+ if ($is_category)
+ {
+ $query.= '
+ AND category_id = '.$_SESSION['bulk_manager_filter']['category'];
+ }
+
+ $query.= '
+ '.$conf['order_by'].'
+ LIMIT '.$page['nb_images'].' OFFSET '.$page['start'].'
+;';
+ $result = pwg_query($query);
+
+ $thumb_params = ImageStdParams::get_by_type(IMG_SQUARE);
+ // template thumbnail initialization
+ while ($row = pwg_db_fetch_assoc($result))
+ {
+ $nb_thumbs_page++;
+ $src_image = new SrcImage($row);
+
+ $ttitle = render_element_name($row);
+ if ($ttitle != get_name_from_file($row['file']))
+ {
+ $ttitle.= ' ('.$row['file'].')';
+ }
+
+ $ttitle.= '
'.$row['width'].'×'.$row['height'].' pixels, '.sprintf('%.2f', $row['filesize']/1024).'MB';
+
+ $template->append(
+ 'thumbnails', array_merge($row,
+ array(
+ 'thumb' => new DerivativeImage($thumb_params, $src_image),
+ 'TITLE' => $ttitle,
+ 'FILE_SRC' => DerivativeImage::url(IMG_LARGE, $src_image),
+ 'U_EDIT' => get_root_url().'admin.php?page=photo-'.$row['id'],
+ )
+ ));
+ }
+ $template->assign('thumb_params', $thumb_params);
+}
+
+$template->assign(array(
+ 'nb_thumbs_page' => $nb_thumbs_page,
+ 'nb_thumbs_set' => count($page['cat_elements_id']),
+ 'CACHE_KEYS' => get_admin_client_cache_keys(array('tags', 'categories')),
+ ));
+
+trigger_notify('loc_end_element_set_global');
+
+//----------------------------------------------------------- sending html code
+$template->assign_var_from_handle('ADMIN_CONTENT', 'batch_manager_global');
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/batch_manager_unit.php b/Piwingo/piwigo-data/piwigo/admin/batch_manager_unit.php
new file mode 100644
index 0000000..d2d8751
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/batch_manager_unit.php
@@ -0,0 +1,424 @@
+ array('id'),
+ 'update' => array('name','author','level','comment','date_creation')
+ ),
+ $datas
+ );
+
+ $page['infos'][] = l10n('Photo informations updated');
+ invalidate_user_cache();
+}
+
+//collection
+$collection = array();
+if (isset($_POST['nb_photos_deleted']))
+{
+ check_input_parameter('nb_photos_deleted', $_POST, false, '/^\d+$/');
+
+ // let's fake a collection (we don't know the image_ids so we use "null", we only
+ // care about the number of items here)
+ $collection = array_fill(0, $_POST['nb_photos_deleted'], null);
+}
+else if (isset($_POST['setSelected']))
+{
+ // Here we don't use check_input_parameter because preg_match has a limit in
+ // the repetitive pattern. Found a limit to 3276 but may depend on memory.
+ //
+ // check_input_parameter('whole_set', $_POST, false, '/^\d+(,\d+)*$/');
+ //
+ // Instead, let's break the input parameter into pieces and check pieces one by one.
+ $collection = explode(',', $_POST['whole_set']);
+
+ foreach ($collection as $id)
+ {
+ if (!preg_match('/^\d+$/', $id))
+ {
+ fatal_error('[Hacking attempt] the input parameter "whole_set" is not valid');
+ }
+ }
+}
+else if (isset($_POST['selection']))
+{
+ $collection = $_POST['selection'];
+}
+
+
+// +-----------------------------------------------------------------------+
+// | template init |
+// +-----------------------------------------------------------------------+
+
+$template->set_filenames(
+ array('batch_manager_unit' => 'batch_manager_unit.tpl'));
+
+$base_url = PHPWG_ROOT_PATH.'admin.php';
+
+
+$template->assign(
+ array(
+
+ 'U_ELEMENTS_PAGE' => $base_url.get_query_string_diff(array('display','start')),
+ 'level_options' => get_privacy_level_options(),
+ 'ADMIN_PAGE_TITLE' => l10n('Batch Manager'),
+ 'PWG_TOKEN' => get_pwg_token(),
+ )
+ );
+ include(PHPWG_ROOT_PATH.'admin/include/batch_manager_filters.inc.php');
+// +-----------------------------------------------------------------------+
+// | global mode thumbnails |
+// +-----------------------------------------------------------------------+
+
+$template->assign('ACTIVE_PLUGINS', array_keys($pwg_loaded_plugins));
+
+// how many items to display on this page
+if (!empty($_GET['display']))
+{
+ // conf_update_param('batch_manager_images_per_page_unit' , intval($_GET['display']));
+ // $page['nb_images'] = $conf['batch_manager_images_per_page_unit'];
+ $page['nb_images'] = intval($_GET['display']);
+}
+elseif (in_array($conf['batch_manager_images_per_page_unit'], array(5, 10, 50)))
+{
+ $page['nb_images'] = $conf['batch_manager_images_per_page_unit'];
+}
+else
+{
+ $page['nb_images'] = 5;
+}
+$template->assign('per_page', $page['nb_images']);
+
+if (count($page['cat_elements_id']) > 0)
+{
+ $nav_bar = create_navigation_bar(
+ $base_url.get_query_string_diff(array('start')),
+ count($page['cat_elements_id']),
+ $page['start'],
+ $page['nb_images']
+ );
+ $template->assign(array('navbar' => $nav_bar));
+
+ $element_ids = array();
+
+ $is_category = false;
+ if (isset($_SESSION['bulk_manager_filter']['category'])
+ and !isset($_SESSION['bulk_manager_filter']['category_recursive']))
+ {
+ $is_category = true;
+ }
+
+ if (isset($_SESSION['bulk_manager_filter']['prefilter'])
+ and 'duplicates' == $_SESSION['bulk_manager_filter']['prefilter'])
+ {
+ $conf['order_by'] = ' ORDER BY file, id';
+ }
+
+
+ $query = '
+SELECT *
+ FROM '.IMAGES_TABLE;
+
+ if ($is_category)
+ {
+ $category_info = get_cat_info($_SESSION['bulk_manager_filter']['category']);
+
+ $conf['order_by'] = $conf['order_by_inside_category'];
+ if (!empty($category_info['image_order']))
+ {
+ $conf['order_by'] = ' ORDER BY '.$category_info['image_order'];
+ }
+
+ $query.= '
+ JOIN '.IMAGE_CATEGORY_TABLE.' ON id = image_id';
+ }
+
+ $query.= '
+ WHERE id IN ('.implode(',', $page['cat_elements_id']).')';
+
+ if ($is_category)
+ {
+ $query.= '
+ AND category_id = '.$_SESSION['bulk_manager_filter']['category'];
+ }
+
+ $query.= '
+ '.$conf['order_by'].'
+ LIMIT '.$page['nb_images'].' OFFSET '.$page['start'].'
+;';
+ // $result = pwg_query($query);
+ $images = query2array($query);
+ $added_by_ids = array_unique(array_column($images, 'added_by'));
+ if (count($added_by_ids) > 0)
+ {
+ $query = '
+SELECT
+ '.$conf['user_fields']['username'].' AS username,
+ '.$conf['user_fields']['id'].' AS id
+ FROM '.USERS_TABLE.'
+ WHERE '.$conf['user_fields']['id'].' IN ( '.implode(',', $added_by_ids).' )
+;';
+ $added_by_username_of = query2array($query, 'id', 'username');
+ }
+
+ $storage_category_id = null;
+ if (!empty($row['storage_category_id']))
+ {
+ $storage_category_id = $row['storage_category_id'];
+ }
+
+ foreach ($images as $row)
+ {
+ $element_ids[] = $row['id'];
+
+ $src_image = new SrcImage($row);
+
+ $image_file = $row['file'];
+
+
+
+ $query = '
+SELECT
+ id,
+ name
+ FROM '.IMAGE_TAG_TABLE.' AS it
+ JOIN '.TAGS_TABLE.' AS t ON t.id = it.tag_id
+ WHERE image_id = '.$row['id'].'
+;';
+
+ $tag_selection = get_taglist($query);
+
+ $legend = render_element_name($row);
+ if ($legend != get_name_from_file($row['file']))
+ {
+ $legend.= ' ('.$row['file'].')';
+ }
+ $extTab = explode('.',$row['path']);
+
+
+
+// represent
+
+ // categories
+
+ $query = '
+ SELECT category_id, uppercats, dir
+ FROM '.IMAGE_CATEGORY_TABLE.' AS ic
+ INNER JOIN '.CATEGORIES_TABLE.' AS c
+ ON c.id = ic.category_id
+ WHERE image_id = '.$row['id'].'
+ ;';
+
+ $sub_result = pwg_query($query);
+ $related_categories = array();
+ $related_category_ids = array();
+ $media['image'] = get_image_infos($row['id'], true);
+
+ while ($item = pwg_db_fetch_assoc($sub_result))
+ {
+ $name =
+ get_cat_display_name_cache(
+ $item['uppercats'],
+ get_root_url().'admin.php?page=album-'
+ );
+
+ if ($item['category_id'] == $storage_category_id)
+ {
+ $template->assign('STORAGE_CATEGORY', $name);
+ }
+
+ $related_categories[$item['category_id']] = array('name' => $name, 'unlinkable' => $item['category_id'] != $storage_category_id);
+ $related_category_ids[] = $item['category_id'];
+ }
+
+ // jump to link
+ $image_file = $row['file'];
+
+ $query = '
+ SELECT category_id
+ FROM '.IMAGE_CATEGORY_TABLE.'
+ WHERE image_id = '.$row['id'].'
+ ;';
+ $authorizeds = array_diff(
+ array_from_query($query, 'category_id'),
+ explode(
+ ',',
+ calculate_permissions($user['id'], $user['status'])
+ )
+ );
+
+ if (isset($row['cat_id'])
+ and in_array($row['cat_id'], $authorizeds))
+ {
+ $url_img = make_picture_url(
+ array(
+ 'image_id' => $row['id'],
+ 'image_file' => $image_file,
+ 'category' => $cache['cat_names'][ $row['cat_id'] ],
+ )
+ );
+ }
+ else
+ {
+ foreach ($authorizeds as $category)
+ {
+ $url_img = make_picture_url(
+ array(
+ 'image_id' => $row['id'], //utile ?
+ 'image_file' => $image_file,
+ 'category' => $cache['cat_names'][ $category ],
+ )
+ );
+ break;
+ }
+ }
+ $admin_photo_base_url = get_root_url().'admin.php?page=photo-'.$row['id'];
+ $admin_url_start = $admin_photo_base_url.'-properties';
+ $admin_url_start.= isset($row['cat_id']) ? '&cat_id='.$row['cat_id'] : '';
+ $selected_level = isset($row['level']) ? $row['level'] : $row['level'];
+
+
+ $template->append(
+ 'elements', array_merge($row,
+ array(
+ 'ID' => $row['id'],
+ 'TN_SRC' => DerivativeImage::url(IMG_MEDIUM, $src_image),
+ 'FILE_SRC' => DerivativeImage::url(IMG_LARGE, $src_image),
+ 'LEGEND' => $legend,
+ 'U_EDIT' => get_root_url().'admin.php?page=photo-'.$row['id'],
+ 'NAME' => htmlspecialchars(isset($row['name']) ? $row['name'] : ""),
+ 'AUTHOR' => htmlspecialchars(isset($row['author']) ? $row['author'] : ""),
+ 'LEVEL' => !empty($row['level'])?$row['level']:'0',
+ 'DESCRIPTION' => htmlspecialchars(isset($row['comment']) ? $row['comment'] : ""),
+ 'DATE_CREATION' => $row['date_creation'],
+ 'TAGS' => $tag_selection,
+ 'is_svg' => (strtoupper(end($extTab)) == 'SVG'),
+ 'TITLE' => render_element_name($row),
+ 'DIMENSIONS' => @$row['width'].'x'.@$row['height'].' px',
+ 'FORMAT' => ($row['width'] >= $row['height'])? 1:0,//0:horizontal, 1:vertical
+ 'FILESIZE' => l10n('%.2f MB',$row['filesize']/1024),
+ 'REGISTRATION_DATE' => format_date($row['date_available']),
+ 'EXT' => l10n('%s file type',end($extTab)),
+ 'POST_DATE' => l10n('Added on %s', format_date($row['date_available'], array('day', 'month', 'year'))),
+ 'AGE' => l10n(ucfirst(time_since($row['date_available'], 'year'))),
+ 'ADDED_BY' => l10n('Added by %s', $added_by_username_of[ $row['added_by'] ] ?? l10n('N/A')),
+ 'STATS' => l10n('Visited %d times', $row['hit']),
+ 'FILE' => l10n('%s', $row['file']),
+ 'related_categories' => $related_categories,
+ 'related_category_ids' => json_encode($related_category_ids),
+ 'U_JUMPTO' => (isset($url_img) and $user['level'] >= $media['image']['level']) ? $url_img : null,
+ 'tag_selection' => $tag_selection,
+ 'U_DOWNLOAD' => 'action.php?id='.$row['id'].'&part=e&pwg_token='.get_pwg_token().'&download',
+ 'U_HISTORY' => get_root_url().'admin.php?page=history&filter_image_id='.$row['id'],
+ 'U_ACTIVITY' => get_root_url().'admin.php?page=user_activity&photo='.$row['id'],
+ 'U_DELETE' => $admin_url_start.'&delete=1&pwg_token='.get_pwg_token(),
+ 'U_SYNC' => $admin_url_start.'&sync_metadata=1',
+ 'PATH'=>$row['path'],
+ 'level_options_selected' => array($selected_level)
+
+
+ )
+ ));
+ }
+
+ $template->assign(array(
+ 'ELEMENT_IDS' => implode(',', $element_ids),
+ ));
+}
+
+$template->assign(array(
+ 'CACHE_KEYS' => get_admin_client_cache_keys(array('tags', 'categories')),
+));
+
+trigger_notify('loc_end_element_set_unit');
+
+// +-----------------------------------------------------------------------+
+// | sending html code |
+// +-----------------------------------------------------------------------+
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'batch_manager_unit');
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/cat_list.php b/Piwingo/piwigo-data/piwigo/admin/cat_list.php
new file mode 100644
index 0000000..0d7b38a
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/cat_list.php
@@ -0,0 +1,355 @@
+ l10n('Album name, A → Z'),
+ 'name DESC' => l10n('Album name, Z → A'),
+ 'date_creation DESC' => l10n('Date created, new → old').' '.l10n('(determined from photos)'),
+ 'date_creation ASC' => l10n('Date created, old → new').' '.l10n('(determined from photos)'),
+ 'date_available DESC' => l10n('Date posted, new → old').' '.l10n('(determined from photos)'),
+ 'date_available ASC' => l10n('Date posted, old → new').' '.l10n('(determined from photos)'),
+ );
+
+// +-----------------------------------------------------------------------+
+// | functions |
+// +-----------------------------------------------------------------------+
+
+
+
+function get_categories_ref_date($ids, $field='date_available', $minmax='max')
+{
+ // we need to work on the whole tree under each category, even if we don't
+ // want to sort sub categories
+ $category_ids = get_subcat_ids($ids);
+
+ // search for the reference date of each album
+ $query = '
+SELECT
+ category_id,
+ '.$minmax.'('.$field.') as ref_date
+ FROM '.IMAGE_CATEGORY_TABLE.'
+ JOIN '.IMAGES_TABLE.' ON image_id = id
+ WHERE category_id IN ('.implode(',', $category_ids).')
+ GROUP BY category_id
+;';
+ $ref_dates = query2array($query, 'category_id', 'ref_date');
+
+ // the iterate on all albums (having a ref_date or not) to find the
+ // reference_date, with a search on sub-albums
+ $query = '
+SELECT
+ id,
+ uppercats
+ FROM '.CATEGORIES_TABLE.'
+ WHERE id IN ('.implode(',', $category_ids).')
+;';
+ $uppercats_of = query2array($query, 'id', 'uppercats');
+
+ foreach (array_keys($uppercats_of) as $cat_id)
+ {
+ // find the subcats
+ $subcat_ids = array();
+
+ foreach ($uppercats_of as $id => $uppercats)
+ {
+ if (preg_match('/(^|,)'.$cat_id.'(,|$)/', $uppercats))
+ {
+ $subcat_ids[] = $id;
+ }
+ }
+
+ $to_compare = array();
+ foreach ($subcat_ids as $id)
+ {
+ if (isset($ref_dates[$id]))
+ {
+ $to_compare[] = $ref_dates[$id];
+ }
+ }
+
+ if (count($to_compare) > 0)
+ {
+ $ref_dates[$cat_id] = 'max' == $minmax ? max($to_compare) : min($to_compare);
+ }
+ else
+ {
+ $ref_dates[$cat_id] = null;
+ }
+ }
+
+ // only return the list of $ids, not the sub-categories
+ $return = array();
+ foreach ($ids as $id)
+ {
+ $return[$id] = $ref_dates[$id];
+ }
+
+ return $return;
+}
+
+// +-----------------------------------------------------------------------+
+// | initialization |
+// +-----------------------------------------------------------------------+
+
+check_input_parameter('parent_id', $_GET, false, PATTERN_ID);
+
+$categories = array();
+
+$base_url = get_root_url().'admin.php?page=cat_list';
+$navigation = '';
+$navigation.= l10n('Home');
+$navigation.= '';
+
+// +-----------------------------------------------------------------------+
+// | tabs |
+// +-----------------------------------------------------------------------+
+
+$page['tab'] = 'list';
+include(PHPWG_ROOT_PATH.'admin/include/albums_tab.inc.php');
+
+// +-----------------------------------------------------------------------+
+// | virtual categories management |
+// +-----------------------------------------------------------------------+
+// request to delete a virtual category
+if (isset($_GET['delete']) and is_numeric($_GET['delete']))
+{
+ $photo_deletion_mode = 'no_delete';
+ if (isset($_GET['photo_deletion_mode']))
+ {
+ $photo_deletion_mode = $_GET['photo_deletion_mode'];
+ }
+ delete_categories(array($_GET['delete']), $photo_deletion_mode);
+
+ $_SESSION['page_infos'] = array(l10n('Virtual album deleted'));
+ update_global_rank();
+ invalidate_user_cache();
+
+ $redirect_url = get_root_url().'admin.php?page=cat_list';
+ if (isset($_GET['parent_id']))
+ {
+ $redirect_url.= '&parent_id='.$_GET['parent_id'];
+ }
+ redirect($redirect_url);
+}
+// request to add a virtual category
+elseif (isset($_POST['submitAdd']))
+{
+ $output_create = create_virtual_category(
+ $_POST['virtual_name'],
+ @$_GET['parent_id']
+ );
+
+ invalidate_user_cache();
+ if (isset($output_create['error']))
+ {
+ $page['errors'][] = $output_create['error'];
+ }
+ else
+ {
+ $edit_url = get_root_url().'admin.php?page=album-'.$output_create['id'];
+ $page['infos'][] = $output_create['info'].' '.l10n('Edit album').'';
+ }
+}
+// +-----------------------------------------------------------------------+
+// | Navigation path |
+// +-----------------------------------------------------------------------+
+
+if (isset($_GET['parent_id']))
+{
+ $navigation.= $conf['level_separator'];
+
+ $navigation.= get_cat_display_name_from_id(
+ $_GET['parent_id'],
+ $base_url.'&parent_id='
+ );
+}
+// +-----------------------------------------------------------------------+
+// | template initialization |
+// +-----------------------------------------------------------------------+
+$template->set_filename('categories', 'cat_list.tpl');
+
+$form_action = PHPWG_ROOT_PATH.'admin.php?page=cat_list';
+if (isset($_GET['parent_id']))
+{
+ $form_action.= '&parent_id='.$_GET['parent_id'];
+}
+$sort_orders_checked = array_keys($sort_orders);
+
+$template->assign(array(
+ 'ADMIN_PAGE_TITLE' => l10n('Album list management'),
+ 'CATEGORIES_NAV'=> preg_replace("# {2,}#"," ",preg_replace("#(\r\n|\n\r|\n|\r)#"," ",$navigation)),
+ 'F_ACTION'=>$form_action,
+ 'PWG_TOKEN' => get_pwg_token(),
+ 'sort_orders' => $sort_orders,
+ 'sort_order_checked' => array_shift($sort_orders_checked),
+ ));
+
+// +-----------------------------------------------------------------------+
+// | Categories display |
+// +-----------------------------------------------------------------------+
+
+$categories = array();
+
+$query = '
+SELECT id, name, permalink, dir, `rank`, status
+ FROM '.CATEGORIES_TABLE;
+if (!isset($_GET['parent_id']))
+{
+ $query.= '
+ WHERE id_uppercat IS NULL';
+}
+else
+{
+ $query.= '
+ WHERE id_uppercat = '.$_GET['parent_id'];
+}
+$query.= '
+ ORDER BY `rank` ASC
+;';
+$categories = hash_from_query($query, 'id');
+
+// get the categories containing images directly
+$categories_with_images = array();
+if (count($categories))
+{
+ $query = '
+SELECT
+ category_id,
+ COUNT(*) AS nb_photos
+ FROM '.IMAGE_CATEGORY_TABLE.'
+ GROUP BY category_id
+;';
+ // WHERE category_id IN ('.implode(',', array_keys($categories)).')
+
+ $nb_photos_in = query2array($query, 'category_id', 'nb_photos');
+
+ $query = '
+SELECT
+ id,
+ uppercats
+ FROM '.CATEGORIES_TABLE.'
+;';
+ $all_categories = query2array($query, 'id', 'uppercats');
+ $subcats_of = array();
+
+ foreach ($all_categories as $id => $uppercats)
+ {
+ foreach (array_slice(explode(',', $uppercats), 0, -1) as $uppercat_id)
+ {
+ @$subcats_of[$uppercat_id][] = $id;
+ }
+ }
+
+ $nb_sub_photos = array();
+ foreach ($subcats_of as $cat_id => $subcat_ids)
+ {
+ $nb_photos = 0;
+ foreach ($subcat_ids as $id)
+ {
+ if (isset($nb_photos_in[$id]))
+ {
+ $nb_photos+= $nb_photos_in[$id];
+ }
+ }
+
+ $nb_sub_photos[$cat_id] = $nb_photos;
+ }
+}
+
+$template->assign('categories', array());
+$base_url = get_root_url().'admin.php?page=';
+
+if (isset($_GET['parent_id']))
+{
+ $template->assign(
+ 'PARENT_EDIT',
+ $base_url.'album-'.$_GET['parent_id']
+ );
+}
+
+foreach ($categories as $category)
+{
+ $cat_list_url = $base_url.'cat_list';
+
+ $self_url = $cat_list_url;
+ if (isset($_GET['parent_id']))
+ {
+ $self_url.= '&parent_id='.$_GET['parent_id'];
+ }
+
+ $tpl_cat =
+ array(
+ 'NAME' =>
+ trigger_change(
+ 'render_category_name',
+ $category['name'],
+ 'admin_cat_list'
+ ),
+ 'NB_PHOTOS' => isset($nb_photos_in[$category['id']]) ? $nb_photos_in[$category['id']] : 0,
+ 'NB_SUB_PHOTOS' => isset($nb_sub_photos[$category['id']]) ? $nb_sub_photos[$category['id']] : 0,
+ 'NB_SUB_ALBUMS' => isset($subcats_of[$category['id']]) ? count($subcats_of[$category['id']]) : 0,
+ 'ID' => $category['id'],
+ 'RANK' => $category['rank']*10,
+
+ 'U_JUMPTO' => make_index_url(
+ array(
+ 'category' => $category
+ )
+ ),
+
+ 'U_CHILDREN' => $cat_list_url.'&parent_id='.$category['id'],
+ 'U_EDIT' => $base_url.'album-'.$category['id'],
+ 'U_ADD_PHOTOS_ALBUM' => $base_url.'photos_add&album='.$category['id'],
+ 'U_MOVE' => $base_url.'albums#cat-'.$category['id'],
+
+ 'IS_VIRTUAL' => empty($category['dir']),
+ 'CAT_ADMIN_ACCESS' => cat_admin_access($category['id']),
+ );
+
+ if (empty($category['dir']))
+ {
+ $tpl_cat['U_DELETE'] = $self_url.'&delete='.$category['id'];
+ $tpl_cat['U_DELETE'].= '&pwg_token='.get_pwg_token();
+ }
+ else
+ {
+ if ($conf['enable_synchronization'])
+ {
+ $tpl_cat['U_SYNC'] = $base_url.'site_update&site=1&cat_id='.$category['id'];
+ }
+ }
+
+ $template->append('categories', $tpl_cat);
+}
+
+trigger_notify('loc_end_cat_list');
+
+// +-----------------------------------------------------------------------+
+// | sending html code |
+// +-----------------------------------------------------------------------+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'categories');
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/cat_modify.php b/Piwingo/piwigo-data/piwigo/admin/cat_modify.php
new file mode 100644
index 0000000..66c2568
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/cat_modify.php
@@ -0,0 +1,394 @@
+ rex > 1_year_old" is on the the same site as the
+// Piwigo files and this category has 22 for identifier
+// get_complete_dir(22) returns "./galleries/pets/rex/1_year_old/"
+function get_complete_dir( $category_id )
+{
+ return get_site_url($category_id).get_local_dir($category_id);
+}
+
+// get_local_dir returns an array with complete path without the site url
+// Example : "pets > rex > 1_year_old" is on the the same site as the
+// Piwigo files and this category has 22 for identifier
+// get_local_dir(22) returns "pets/rex/1_year_old/"
+function get_local_dir( $category_id )
+{
+ global $page;
+
+ $uppercats = '';
+ $local_dir = '';
+
+ if ( isset( $page['plain_structure'][$category_id]['uppercats'] ) )
+ {
+ $uppercats = $page['plain_structure'][$category_id]['uppercats'];
+ }
+ else
+ {
+ $query = 'SELECT uppercats';
+ $query.= ' FROM '.CATEGORIES_TABLE.' WHERE id = '.$category_id;
+ $query.= ';';
+ $row = pwg_db_fetch_assoc( pwg_query( $query ) );
+ $uppercats = $row['uppercats'];
+ }
+
+ $upper_array = explode( ',', $uppercats );
+
+ $database_dirs = array();
+ $query = 'SELECT id,dir';
+ $query.= ' FROM '.CATEGORIES_TABLE.' WHERE id IN ('.$uppercats.')';
+ $query.= ';';
+ $result = pwg_query( $query );
+ while( $row = pwg_db_fetch_assoc( $result ) )
+ {
+ $database_dirs[$row['id']] = $row['dir'];
+ }
+ foreach ($upper_array as $id)
+ {
+ $local_dir.= $database_dirs[$id].'/';
+ }
+
+ return $local_dir;
+}
+
+// retrieving the site url : "http://domain.com/gallery/" or
+// simply "./galleries/"
+function get_site_url($category_id)
+{
+ global $page;
+
+ $query = '
+SELECT galleries_url
+ FROM '.SITES_TABLE.' AS s,'.CATEGORIES_TABLE.' AS c
+ WHERE s.id = c.site_id
+ AND c.id = '.$category_id.'
+;';
+ $row = pwg_db_fetch_assoc(pwg_query($query));
+ return $row['galleries_url'];
+}
+
+function get_min_local_dir($local_dir)
+{
+ $full_dir = explode('/', $local_dir);
+ if (count($full_dir) <= 3)
+ {
+ return $local_dir;
+ }
+ else
+ {
+ $start = $full_dir[0] . '/' . $full_dir[1];
+ $end = end($full_dir);
+ $concat = $start . '/…/' . $end;
+ return $concat;
+ }
+}
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_ADMINISTRATOR);
+
+trigger_notify('loc_begin_cat_modify');
+
+//---------------------------------------------------------------- verification
+if ( !isset( $_GET['cat_id'] ) || !is_numeric( $_GET['cat_id'] ) )
+{
+ trigger_error( 'missing cat_id param', E_USER_ERROR);
+}
+
+//--------------------------------------------------------- form criteria check
+
+if (isset($redirect))
+{
+ redirect($admin_album_base_url.'-properties');
+}
+
+// nullable fields
+foreach (array('comment','dir','site_id', 'id_uppercat') as $nullable)
+{
+ if (!isset($category[$nullable]))
+ {
+ $category[$nullable] = '';
+ }
+}
+
+$category['is_virtual'] = empty($category['dir']) ? true : false;
+
+$query = 'SELECT DISTINCT category_id
+ FROM '.IMAGE_CATEGORY_TABLE.'
+ WHERE category_id = '.$_GET['cat_id'].'
+ LIMIT 1';
+$result = pwg_query($query);
+$category['has_images'] = pwg_db_num_rows($result)>0 ? true : false;
+
+// number of sub-categories
+$subcat_ids = get_subcat_ids(array($category['id']));
+
+$category['nb_subcats'] = count($subcat_ids) - 1;
+
+// Navigation path
+$navigation = get_cat_display_name_cache(
+ $category['uppercats'],
+ get_root_url().'admin.php?page=album-'
+);
+
+// Parent navigation path
+$uppercats_array = explode(',', $category['uppercats']);
+if (count($uppercats_array) > 1)
+{
+ array_pop($uppercats_array);
+ $parent_navigation = get_cat_display_name_cache(
+ implode(',', $uppercats_array),
+ get_root_url().'admin.php?page=album-'
+ );
+}
+else
+{
+ $parent_navigation = l10n('Root');
+}
+
+//----------------------------------------------------- template initialization
+$template->set_filename( 'album_properties', 'cat_modify.tpl');
+
+$base_url = get_root_url().'admin.php?page=';
+$cat_list_url = $base_url.'albums';
+
+$self_url = $cat_list_url;
+if (!empty($category['id_uppercat']))
+{
+ $self_url.= '&parent_id='.$category['id_uppercat'];
+}
+
+// We show or hide this warning in JS
+$page['warnings'][] = l10n('This album is currently locked, visible only to administrators.').''.l10n('Unlock it').'';
+
+$template->assign(
+ array(
+ 'CATEGORIES_NAV' => preg_replace("# {2,}#"," ",preg_replace("#(\r\n|\n\r|\n|\r)#"," ",$navigation)),
+ 'CATEGORIES_PARENT_NAV' => preg_replace("# {2,}#"," ",preg_replace("#(\r\n|\n\r|\n|\r)#"," ",$parent_navigation)),
+ 'PARENT_CAT_ID' => !empty($category['id_uppercat']) ? $category['id_uppercat'] : 0,
+ 'CAT_ID' => $category['id'],
+ 'CAT_NAME' => @htmlspecialchars($category['name']),
+ 'CAT_COMMENT' => @htmlspecialchars($category['comment']),
+ 'IS_VISIBLE' => boolean_to_string($category['visible']),
+ 'CAT_ADMIN_ACCESS' => cat_admin_access($category['id']),
+
+ 'U_DELETE' => $base_url.'albums',
+
+ 'U_JUMPTO' => make_index_url(
+ array(
+ 'category' => $category
+ )
+ ),
+
+ 'U_ADD_PHOTOS_ALBUM' => $base_url.'photos_add&album='.$category['id'],
+ 'U_CHILDREN' => $cat_list_url.'&parent_id='.$category['id'],
+ 'U_MOVE' => $base_url.'albums&parent_id='.$category['id'],
+ 'U_ACTIVITY' => get_root_url().'admin.php?page=user_activity&album='.$category['id'],
+ )
+ );
+
+if ($conf['activate_comments'])
+{
+ $template->assign('CAT_COMMENTABLE', boolean_to_string($category['commentable']));
+}
+
+// manage album elements link
+$image_count = 0;
+$info_title = "";
+if ($category['has_images'])
+{
+ $template->assign(
+ 'U_MANAGE_ELEMENTS',
+ $base_url.'batch_manager&filter=album-'.$category['id']
+ );
+
+ $query = '
+SELECT
+ COUNT(image_id),
+ MIN(DATE(date_available)),
+ MAX(DATE(date_available))
+ FROM '.IMAGES_TABLE.'
+ JOIN '.IMAGE_CATEGORY_TABLE.' ON image_id = id
+ WHERE category_id = '.$category['id'].'
+;';
+ list($image_count, $min_date, $max_date) = pwg_db_fetch_row(pwg_query($query));
+
+ if ($min_date == $max_date)
+ {
+ $info_title = l10n(
+ 'This album contains %d photos, added on %s.',
+ $image_count,
+ format_date($min_date)
+ );
+ }
+ else
+ {
+ $info_title = l10n(
+ 'This album contains %d photos, added between %s and %s.',
+ $image_count,
+ format_date($min_date),
+ format_date($max_date)
+ );
+ }
+
+}
+$info_photos = l10n('%d photos', $image_count);
+
+$template->assign(
+ array(
+ 'INFO_PHOTO' => $info_photos,
+ 'INFO_TITLE' => $info_title
+ )
+ );
+
+// total number of images under this category (including sub-categories)
+ $query = '
+SELECT DISTINCT
+ (image_id)
+ FROM
+ '.IMAGE_CATEGORY_TABLE.'
+ WHERE
+ category_id IN ('.implode(',', $subcat_ids).')
+ ;';
+ $image_ids_recursive = query2array($query, null, 'image_id');
+
+ $category['nb_images_recursive'] = count($image_ids_recursive);
+
+// date creation
+$query = '
+SELECT occured_on
+ FROM `'.ACTIVITY_TABLE.'`
+ WHERE object_id = '.$category['id'].'
+ AND object = "album"
+ AND action = "add"
+';
+$result = query2array($query);
+
+if (count($result) > 0) {
+ $template->assign(
+ array(
+ 'INFO_CREATION_SINCE' => time_since($result[0]['occured_on'], 'day', $format=null, $with_text=true, $with_week=true, $only_last_unit=true),
+ 'INFO_CREATION' => format_date($result[0]['occured_on'], array('day', 'month','year'))
+ )
+ );
+}
+
+// Sub Albums
+$query = '
+SELECT COUNT(*)
+ FROM `'.CATEGORIES_TABLE.'`
+ WHERE id_uppercat = '.$category['id'].'
+';
+$result = query2array($query);
+
+
+$template->assign(
+ array(
+ 'INFO_DIRECT_SUB' => l10n(
+ '%d sub-albums',
+ $result[0]['COUNT(*)']
+ ),
+ )
+ );
+
+$template->assign(array(
+ 'INFO_ID' => l10n('Numeric identifier : %d',$category['id']),
+ 'INFO_LAST_MODIFIED_SINCE' => time_since($category['lastmodified'], 'minute', $format=null, $with_text=true, $with_week=true, $only_last_unit=true),
+ 'INFO_LAST_MODIFIED'=> format_date($category['lastmodified'], array('day', 'month','year')),
+ 'INFO_IMAGES_RECURSIVE' => l10n(
+ '%d including sub-albums',
+ $category['nb_images_recursive']
+ ),
+ 'INFO_SUBCATS' => l10n(
+ '%d in whole branch',
+ $category['nb_subcats']
+ ),
+
+ 'NB_SUBCATS' => $category['nb_subcats'],
+ )
+);
+
+$template->assign(array(
+ 'U_MANAGE_RANKS' => $base_url.'element_set_ranks&cat_id='.$category['id'],
+ 'CACHE_KEYS' => get_admin_client_cache_keys(array('categories')),
+ ));
+
+if (!$category['is_virtual'])
+{
+ $category['cat_full_dir'] = get_complete_dir($_GET['cat_id']);
+ $category_full_dir = preg_replace('/\/$/', '', $category['cat_full_dir']);
+ $template->assign(
+ array(
+ 'CAT_FULL_DIR' => $category_full_dir
+ )
+ );
+ $template->assign('CAT_DIR_NAME', basename($category_full_dir));
+ $template->assign('CAT_MIN_DIR', get_min_local_dir($category_full_dir));
+
+ if ($conf['enable_synchronization'])
+ {
+ $template->assign(
+ 'U_SYNC',
+ $base_url.'site_update&site='.$category['site_id'].'&cat_id='.$category['id']
+ );
+ }
+
+}
+
+// representant management
+if ($category['has_images'] or !empty($category['representative_picture_id']))
+{
+ $tpl_representant = array();
+
+ // picture to display : the identified representant or the generic random
+ // representant ?
+ if (!empty($category['representative_picture_id']))
+ {
+ $tpl_representant['picture'] = get_category_representant_properties($category['representative_picture_id'], IMG_MEDIUM);
+ }
+
+ // can the admin choose to set a new random representant ?
+ $tpl_representant['ALLOW_SET_RANDOM'] = ($category['has_images'] ? true : false);
+
+ // can the admin delete the current representant ?
+ if (
+ ($category['has_images']
+ and $conf['allow_random_representative'])
+ or
+ (!$category['has_images']
+ and !empty($category['representative_picture_id'])))
+ {
+ $tpl_representant['ALLOW_DELETE'] = true;
+ }
+ $template->assign('representant', $tpl_representant);
+}
+
+if ($category['is_virtual'])
+{
+ $template->assign('parent_category', empty($category['id_uppercat']) ? array() : array($category['id_uppercat']));
+}
+
+$template->assign('PWG_TOKEN', get_pwg_token());
+
+trigger_notify('loc_end_cat_modify');
+
+//----------------------------------------------------------- sending html code
+$template->assign_var_from_handle('ADMIN_CONTENT', 'album_properties');
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/cat_options.php b/Piwingo/piwigo-data/piwigo/admin/cat_options.php
new file mode 100644
index 0000000..e722c0e
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/cat_options.php
@@ -0,0 +1,253 @@
+ 0)
+{
+ switch ($_GET['section'])
+ {
+ case 'comments' :
+ {
+ $query = '
+UPDATE '.CATEGORIES_TABLE.'
+ SET commentable = \'false\'
+ WHERE id IN ('.implode(',', $_POST['cat_true']).')
+;';
+ pwg_query($query);
+ break;
+ }
+ case 'visible' :
+ {
+ set_cat_visible($_POST['cat_true'], 'false');
+ break;
+ }
+ case 'status' :
+ {
+ set_cat_status($_POST['cat_true'], 'private');
+ break;
+ }
+ case 'representative' :
+ {
+ $query = '
+UPDATE '.CATEGORIES_TABLE.'
+ SET representative_picture_id = NULL
+ WHERE id IN ('.implode(',', $_POST['cat_true']).')
+;';
+ pwg_query($query);
+ break;
+ }
+ }
+
+ pwg_activity('album', $_POST['cat_true'], 'edit', array('section'=>$_GET['section'], 'action'=>'falsify'));
+}
+else if (isset($_POST['trueify'])
+ and isset($_POST['cat_false'])
+ and count($_POST['cat_false']) > 0)
+{
+ switch ($_GET['section'])
+ {
+ case 'comments' :
+ {
+ $query = '
+UPDATE '.CATEGORIES_TABLE.'
+ SET commentable = \'true\'
+ WHERE id IN ('.implode(',', $_POST['cat_false']).')
+;';
+ pwg_query($query);
+ break;
+ }
+ case 'visible' :
+ {
+ set_cat_visible($_POST['cat_false'], 'true');
+ break;
+ }
+ case 'status' :
+ {
+ set_cat_status($_POST['cat_false'], 'public');
+ break;
+ }
+ case 'representative' :
+ {
+ // theoretically, all categories in $_POST['cat_false'] contain at
+ // least one element, so Piwigo can find a representant.
+ set_random_representant($_POST['cat_false']);
+ break;
+ }
+ }
+
+ pwg_activity('album', $_POST['cat_false'], 'edit', array('section'=>$_GET['section'], 'action'=>'trueify'));
+}
+
+// +-----------------------------------------------------------------------+
+// | template init |
+// +-----------------------------------------------------------------------+
+
+$template->set_filenames(
+ array(
+ 'cat_options' => 'cat_options.tpl',
+ 'double_select' => 'double_select.tpl'
+ )
+ );
+
+$page['section'] = isset($_GET['section']) ? $_GET['section'] : 'status';
+$base_url = PHPWG_ROOT_PATH.'admin.php?page=cat_options§ion=';
+
+$template->assign(
+ array(
+ 'U_HELP' => get_root_url().'admin/popuphelp.php?page=cat_options',
+ 'F_ACTION'=>$base_url.$page['section']
+ )
+ );
+
+// TabSheet
+$tabsheet = new tabsheet();
+$tabsheet->set_id('cat_options');
+$tabsheet->select($page['section']);
+$tabsheet->assign();
+
+// +-----------------------------------------------------------------------+
+// | form display |
+// +-----------------------------------------------------------------------+
+
+// for each section, categories in the multiselect field can be :
+//
+// - true : commentable for comment section
+// - false : un-commentable for comment section
+// - NA : (not applicable) for virtual categories
+//
+// for true and false status, we associates an array of category ids,
+// function display_select_categories will use the given CSS class for each
+// option
+$cats_true = array();
+$cats_false = array();
+switch ($page['section'])
+{
+ case 'comments' :
+ {
+ $query_true = '
+SELECT id,name,uppercats,global_rank
+ FROM '.CATEGORIES_TABLE.'
+ WHERE commentable = \'true\'
+;';
+ $query_false = '
+SELECT id,name,uppercats,global_rank
+ FROM '.CATEGORIES_TABLE.'
+ WHERE commentable = \'false\'
+;';
+ $template->assign(
+ array(
+ 'L_SECTION' => l10n('Authorize users to add comments on selected albums'),
+ 'L_CAT_OPTIONS_TRUE' => l10n('Authorized'),
+ 'L_CAT_OPTIONS_FALSE' => l10n('Forbidden'),
+ )
+ );
+ break;
+ }
+ case 'visible' :
+ {
+ $query_true = '
+SELECT id,name,uppercats,global_rank
+ FROM '.CATEGORIES_TABLE.'
+ WHERE visible = \'true\'
+;';
+ $query_false = '
+SELECT id,name,uppercats,global_rank
+ FROM '.CATEGORIES_TABLE.'
+ WHERE visible = \'false\'
+;';
+ $template->assign(
+ array(
+ 'L_SECTION' => l10n('Lock albums'),
+ 'L_CAT_OPTIONS_TRUE' => l10n('Unlocked'),
+ 'L_CAT_OPTIONS_FALSE' => l10n('Locked'),
+ )
+ );
+ break;
+ }
+ case 'status' :
+ {
+ $query_true = '
+SELECT id,name,uppercats,global_rank
+ FROM '.CATEGORIES_TABLE.'
+ WHERE status = \'public\'
+;';
+ $query_false = '
+SELECT id,name,uppercats,global_rank
+ FROM '.CATEGORIES_TABLE.'
+ WHERE status = \'private\'
+;';
+ $template->assign(
+ array(
+ 'L_SECTION' => l10n('Manage authorizations for selected albums'),
+ 'L_CAT_OPTIONS_TRUE' => l10n('Public'),
+ 'L_CAT_OPTIONS_FALSE' => l10n('Private'),
+ )
+ );
+ break;
+ }
+ case 'representative' :
+ {
+ $query_true = '
+SELECT id,name,uppercats,global_rank
+ FROM '.CATEGORIES_TABLE.'
+ WHERE representative_picture_id IS NOT NULL
+;';
+ $query_false = '
+SELECT DISTINCT id,name,uppercats,global_rank
+ FROM '.CATEGORIES_TABLE.' INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON id=category_id
+ WHERE representative_picture_id IS NULL
+;';
+ $template->assign(
+ array(
+ 'L_SECTION' => l10n('Representative'),
+ 'L_CAT_OPTIONS_TRUE' => l10n('singly represented'),
+ 'L_CAT_OPTIONS_FALSE' => l10n('randomly represented')
+ )
+ );
+ break;
+ }
+}
+display_select_cat_wrapper($query_true,array(),'category_option_true');
+display_select_cat_wrapper($query_false,array(),'category_option_false');
+$template->assign('PWG_TOKEN',get_pwg_token());
+$template->assign('ADMIN_PAGE_TITLE', l10n('Properties of abums'));
+
+// +-----------------------------------------------------------------------+
+// | sending html code |
+// +-----------------------------------------------------------------------+
+
+$template->assign_var_from_handle('DOUBLE_SELECT', 'double_select');
+$template->assign_var_from_handle('ADMIN_CONTENT', 'cat_options');
+?>
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/cat_perm.php b/Piwingo/piwigo-data/piwigo/admin/cat_perm.php
new file mode 100644
index 0000000..7478da5
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/cat_perm.php
@@ -0,0 +1,303 @@
+ 0)
+ {
+ // if you forbid access to an album, all sub-albums become
+ // automatically forbidden
+ $query = '
+DELETE
+ FROM '.GROUP_ACCESS_TABLE.'
+ WHERE group_id IN ('.implode(',', $deny_groups).')
+ AND cat_id IN ('.implode(',', get_subcat_ids(array($page['cat']))).')
+;';
+ pwg_query($query);
+ }
+
+ //
+ // add permissions to groups
+ //
+ $grant_groups = $_POST['groups'];
+ if (count($grant_groups) > 0)
+ {
+ $cat_ids = get_uppercat_ids(array($page['cat']));
+ if (isset($_POST['apply_on_sub']))
+ {
+ $cat_ids = array_merge($cat_ids, get_subcat_ids(array($page['cat'])));
+ }
+
+ $query = '
+SELECT id
+ FROM '.CATEGORIES_TABLE.'
+ WHERE id IN ('.implode(',', $cat_ids).')
+ AND status = \'private\'
+;';
+ $private_cats = array_from_query($query, 'id');
+
+ $inserts = array();
+ foreach ($private_cats as $cat_id)
+ {
+ foreach ($grant_groups as $group_id)
+ {
+ $inserts[] = array(
+ 'group_id' => $group_id,
+ 'cat_id' => $cat_id
+ );
+ }
+ }
+
+ mass_inserts(
+ GROUP_ACCESS_TABLE,
+ array('group_id','cat_id'),
+ $inserts,
+ array('ignore'=>true)
+ );
+ }
+
+ //
+ // users
+ //
+ $query = '
+SELECT user_id
+ FROM '.USER_ACCESS_TABLE.'
+ WHERE cat_id = '.$page['cat'].'
+;';
+ $users_granted = array_from_query($query, 'user_id');
+
+ if (!isset($_POST['users']))
+ {
+ $_POST['users'] = array();
+ }
+
+ //
+ // remove permissions to users
+ //
+ $deny_users = array_diff($users_granted, $_POST['users']);
+ if (count($deny_users) > 0)
+ {
+ // if you forbid access to an album, all sub-album become automatically
+ // forbidden
+ $query = '
+DELETE
+ FROM '.USER_ACCESS_TABLE.'
+ WHERE user_id IN ('.implode(',', $deny_users).')
+ AND cat_id IN ('.implode(',', get_subcat_ids(array($page['cat']))).')
+;';
+ pwg_query($query);
+ }
+
+ //
+ // add permissions to users
+ //
+ $grant_users = $_POST['users'];
+ if (count($grant_users) > 0)
+ {
+ add_permission_on_category($page['cat'], $grant_users);
+ }
+ }
+
+ $template->assign(
+ array(
+ 'save_success' =>l10n('Album updated successfully'),
+ )
+ );
+
+}
+
+// +-----------------------------------------------------------------------+
+// | template initialization |
+// +-----------------------------------------------------------------------+
+
+$template->set_filename('cat_perm', 'cat_perm.tpl');
+
+$template->assign(
+ array(
+ 'CATEGORIES_NAV' =>
+ get_cat_display_name_from_id(
+ $page['cat'],
+ 'admin.php?page=album-'
+ ),
+ 'U_HELP' => get_root_url().'admin/popuphelp.php?page=cat_perm',
+ 'F_ACTION' => $admin_album_base_url.'-permissions',
+ 'private' => ('private' == $category['status']),
+ )
+ );
+
+// +-----------------------------------------------------------------------+
+// | form construction |
+// +-----------------------------------------------------------------------+
+
+// groups denied are the groups not granted. So we need to find all groups
+// minus groups granted to find groups denied.
+
+$groups = array();
+
+$query = '
+SELECT id, name
+ FROM `'.GROUPS_TABLE.'`
+ ORDER BY name ASC
+;';
+$groups = simple_hash_from_query($query, 'id', 'name');
+$template->assign('groups', $groups);
+
+// groups granted to access the category
+$query = '
+SELECT group_id
+ FROM '.GROUP_ACCESS_TABLE.'
+ WHERE cat_id = '.$page['cat'].'
+;';
+$group_granted_ids = array_from_query($query, 'group_id');
+$template->assign('groups_selected', $group_granted_ids);
+
+// users...
+$users = array();
+
+$query = '
+SELECT '.$conf['user_fields']['id'].' AS id,
+ '.$conf['user_fields']['username'].' AS username
+ FROM '.USERS_TABLE.'
+;';
+$users = simple_hash_from_query($query, 'id', 'username');
+$template->assign('users', $users);
+
+
+$query = '
+SELECT user_id
+ FROM '.USER_ACCESS_TABLE.'
+ WHERE cat_id = '.$page['cat'].'
+;';
+$user_granted_direct_ids = array_from_query($query, 'user_id');
+$template->assign('users_selected', $user_granted_direct_ids);
+
+
+$user_granted_indirect_ids = array();
+if (count($group_granted_ids) > 0)
+{
+ $granted_groups = array();
+
+ $query = '
+SELECT user_id, group_id
+ FROM '.USER_GROUP_TABLE.'
+ WHERE group_id IN ('.implode(',', $group_granted_ids).')
+';
+ $result = pwg_query($query);
+ while ($row = pwg_db_fetch_assoc($result))
+ {
+ if (!isset($granted_groups[ $row['group_id'] ]))
+ {
+ $granted_groups[ $row['group_id'] ] = array();
+ }
+ $granted_groups[ $row['group_id'] ][] = $row['user_id'];
+ }
+
+ $user_granted_by_group_ids = array();
+
+ foreach ($granted_groups as $group_users)
+ {
+ $user_granted_by_group_ids = array_merge($user_granted_by_group_ids, $group_users);
+ }
+
+ $user_granted_by_group_ids = array_unique($user_granted_by_group_ids);
+
+ $user_granted_indirect_ids = array_diff(
+ $user_granted_by_group_ids,
+ $user_granted_direct_ids
+ );
+
+ $template->assign('nb_users_granted_indirect', count($user_granted_indirect_ids));
+
+ foreach ($granted_groups as $group_id => $group_users)
+ {
+ $group_usernames = array();
+ foreach ($group_users as $user_id)
+ {
+ if (in_array($user_id, $user_granted_indirect_ids))
+ {
+ $group_usernames[] = $users[$user_id];
+ }
+ }
+
+ $template->append(
+ 'user_granted_indirect_groups',
+ array(
+ 'group_name' => $groups[$group_id],
+ 'group_users' => implode(', ', $group_usernames),
+ )
+ );
+ }
+}
+
+// +-----------------------------------------------------------------------+
+// | sending html code |
+// +-----------------------------------------------------------------------+
+$template->assign(array(
+ 'PWG_TOKEN' => get_pwg_token(),
+ 'INHERIT' => $conf['inheritance_by_default'],
+ 'CACHE_KEYS' => get_admin_client_cache_keys(array('groups', 'users')),
+ ));
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'cat_perm');
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/comments.php b/Piwingo/piwigo-data/piwigo/admin/comments.php
new file mode 100644
index 0000000..133b545
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/comments.php
@@ -0,0 +1,56 @@
+set_filenames(array('comments'=>'comments.tpl'));
+
+$template->assign(
+ array(
+ 'F_ACTION' => get_root_url().'admin.php?page=comments',
+ 'PWG_TOKEN' => get_pwg_token(),
+ )
+ );
+
+// +-----------------------------------------------------------------------+
+// | Tabs |
+// +-----------------------------------------------------------------------+
+
+include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
+
+$my_base_url = get_root_url().'admin.php?page=';
+
+$tabsheet = new tabsheet();
+$tabsheet->set_id('comments');
+$tabsheet->select('');
+$tabsheet->assign();
+
+$template->assign('ADMIN_PAGE_TITLE', l10n('User comments'));
+
+// +-----------------------------------------------------------------------+
+// | sending html code |
+// +-----------------------------------------------------------------------+
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'comments');
+
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/configuration.php b/Piwingo/piwigo-data/piwigo/admin/configuration.php
new file mode 100644
index 0000000..bbc62ca
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/configuration.php
@@ -0,0 +1,707 @@
+ '',
+ 'file ASC' => l10n('File name, A → Z'),
+ 'file DESC' => l10n('File name, Z → A'),
+ 'name ASC' => l10n('Photo title, A → Z'),
+ 'name DESC' => l10n('Photo title, Z → A'),
+ 'date_creation DESC' => l10n('Date created, new → old'),
+ 'date_creation ASC' => l10n('Date created, old → new'),
+ 'date_available DESC' => l10n('Date posted, new → old'),
+ 'date_available ASC' => l10n('Date posted, old → new'),
+ 'rating_score DESC' => l10n('Rating score, high → low'),
+ 'rating_score ASC' => l10n('Rating score, low → high'),
+ 'hit DESC' => l10n('Visits, high → low'),
+ 'hit ASC' => l10n('Visits, low → high'),
+ 'id ASC' => l10n('Numeric identifier, 1 → 9'),
+ 'id DESC' => l10n('Numeric identifier, 9 → 1'),
+ '`rank` ASC' => l10n('Manual sort order'),
+ );
+
+$comments_order = array(
+ 'ASC' => l10n('Show oldest comments first'),
+ 'DESC' => l10n('Show latest comments first'),
+ );
+
+$mail_themes = array(
+ 'clear' => 'Clear',
+ 'dark' => 'Dark',
+ );
+
+//------------------------------ verification and registration of modifications
+if (isset($_POST['submit']))
+{
+ check_pwg_token();
+ $int_pattern = '/^\d+$/';
+
+ switch ($page['section'])
+ {
+ case 'main' :
+ {
+ if ( !isset($conf['order_by_custom']) and !isset($conf['order_by_inside_category_custom']) )
+ {
+ if ( !empty($_POST['order_by']) )
+ {
+ check_input_parameter('order_by', $_POST, true, '/^('.implode('|', array_keys($sort_fields)).')$/');
+
+ $used = array();
+ foreach ($_POST['order_by'] as $i => $val)
+ {
+ if (empty($val) or isset($used[$val]))
+ {
+ unset($_POST['order_by'][$i]);
+ }
+ else
+ {
+ $used[$val] = true;
+ }
+ }
+ if ( !count($_POST['order_by']) )
+ {
+ $page['errors'][] = l10n('No order field selected');
+ }
+ else
+ {
+ // limit to the number of available parameters
+ $order_by = $order_by_inside_category = array_slice($_POST['order_by'], 0, ceil(count($sort_fields)/2));
+
+ // there is no rank outside categories
+ if ( ($i = array_search('`rank` ASC', $order_by)) !== false)
+ {
+ unset($order_by[$i]);
+ }
+
+ // must define a default order_by if user want to order by rank only
+ if ( count($order_by) == 0 )
+ {
+ $order_by = array('id ASC');
+ }
+
+ $_POST['order_by'] = 'ORDER BY '.implode(', ', $order_by);
+ $_POST['order_by_inside_category'] = 'ORDER BY '.implode(', ', $order_by_inside_category);
+ }
+ }
+ else
+ {
+ $page['errors'][] = l10n('No order field selected');
+ }
+ }
+
+ if (empty($_POST['email_admin_on_new_user']))
+ {
+ $_POST['email_admin_on_new_user'] = 'none';
+ }
+ elseif ('all' == $_POST['email_admin_on_new_user_filter'])
+ {
+ $_POST['email_admin_on_new_user'] = 'all';
+ }
+ else
+ {
+ if (empty($_POST['email_admin_on_new_user_filter_group']))
+ {
+ $_POST['email_admin_on_new_user'] = 'all';
+ }
+ else
+ {
+ $_POST['email_admin_on_new_user'] = 'group:'.$_POST['email_admin_on_new_user_filter_group'];
+ }
+ }
+
+ foreach( $main_checkboxes as $checkbox)
+ {
+ $_POST[$checkbox] = empty($_POST[$checkbox])?'false':'true';
+ }
+ break;
+ }
+ case 'watermark' :
+ {
+ include(PHPWG_ROOT_PATH.'admin/include/configuration_watermark_process.inc.php');
+ break;
+ }
+ case 'sizes' :
+ {
+ include(PHPWG_ROOT_PATH.'admin/include/configuration_sizes_process.inc.php');
+ break;
+ }
+ case 'comments' :
+ {
+ // the number of comments per page must be an integer between 5 and 50
+ // included
+ if (!preg_match($int_pattern, $_POST['nb_comment_page'])
+ or $_POST['nb_comment_page'] < 5
+ or $_POST['nb_comment_page'] > 50)
+ {
+ $page['errors'][] = l10n('The number of comments a page must be between 5 and 50 included.');
+ }
+ foreach( $comments_checkboxes as $checkbox)
+ {
+ $_POST[$checkbox] = empty($_POST[$checkbox])?'false':'true';
+ }
+ break;
+ }
+ case 'default' :
+ {
+ // Never go here
+ break;
+ }
+ case 'display' :
+ {
+ if (!preg_match($int_pattern, $_POST['nb_categories_page'])
+ or $_POST['nb_categories_page'] < 4)
+ {
+ $page['errors'][] = l10n('The number of albums a page must be above 4.');
+ }
+ foreach( $display_checkboxes as $checkbox)
+ {
+ $_POST[$checkbox] = empty($_POST[$checkbox])?'false':'true';
+ }
+ foreach( $display_info_checkboxes as $checkbox)
+ {
+ $_POST['picture_informations'][$checkbox] =
+ empty($_POST['picture_informations'][$checkbox])? false : true;
+ }
+ $_POST['picture_informations'] = addslashes(serialize($_POST['picture_informations']));
+ break;
+ }
+ case 'search' :
+ {
+ foreach( $filters_names_checkboxes as $checkbox)
+ {
+ if (empty($_POST['filters_views_box'][$checkbox])){
+ $_POST['filters_views'][$checkbox]['access'] = 'nobody';
+ $_POST['filters_views'][$checkbox]['default'] = false;
+ }
+ else{
+ $_POST['filters_views'][$checkbox]['default'] =
+ empty($_POST['filters_views'][$checkbox]['default'])? false : true;
+ }
+ }
+ $_POST['filters_views']['last_filters_conf'] =
+ empty($_POST['filters_views']['last_filters_conf'])? false : true;
+ $_POST['filters_views'] = addslashes(serialize($_POST['filters_views']));
+ }
+ }
+
+ // updating configuration if no error found
+ if (!in_array($page['section'], array('sizes', 'watermark')) and count($page['errors']) == 0 and is_webmaster())
+ {
+ //echo ''; print_r($_POST); echo '
';
+ $result = pwg_query('SELECT param FROM '.CONFIG_TABLE);
+ while ($row = pwg_db_fetch_assoc($result))
+ {
+ if (isset($_POST[$row['param']]))
+ {
+ $value = $_POST[$row['param']];
+
+ if ('gallery_title' == $row['param'])
+ {
+ if (!$conf['allow_html_descriptions'])
+ {
+ $value = strip_tags($value);
+ }
+ }
+
+ $query = '
+UPDATE '.CONFIG_TABLE.'
+SET value = \''. str_replace("\'", "''", $value).'\'
+WHERE param = \''.$row['param'].'\'
+;';
+ pwg_query($query);
+ }
+ }
+ $template->assign(
+ array(
+ 'save_success' => l10n('Your configuration settings are saved'),
+ )
+ );
+
+ pwg_activity('system', ACTIVITY_SYSTEM_CORE, 'config', array('config_section'=>$page['section']));
+ }
+
+ //------------------------------------------------------ $conf reinitialization
+ load_conf_from_db();
+}
+
+// restore default derivatives settings
+if ('sizes' == $page['section'] and isset($_GET['action']) and 'restore_settings' == $_GET['action'])
+{
+ ImageStdParams::restore_default();
+ clear_derivative_cache();
+
+ // reset conf
+ load_conf_from_db();
+
+ $template->assign(
+ array(
+ 'save_success' => l10n('Your configuration settings are saved'),
+ )
+ );
+
+ pwg_activity('system', ACTIVITY_SYSTEM_CORE, 'config', array('config_section'=>$page['section'],'config_action'=>$_GET['action']));
+}
+
+//----------------------------------------------------- template initialization
+$template->set_filename('config', 'configuration_' . $page['section'] . '.tpl');
+
+// TabSheet
+$tabsheet = new tabsheet();
+$tabsheet->set_id('configuration');
+$tabsheet->select($page['section']);
+$tabsheet->assign();
+
+$action = get_root_url().'admin.php?page=configuration';
+$action.= '§ion='.$page['section'];
+
+$template->assign(
+ array(
+ 'U_HELP' => get_root_url().'admin/popuphelp.php?page=configuration',
+ 'PWG_TOKEN' => get_pwg_token(),
+ 'F_ACTION'=>$action
+ ));
+
+switch ($page['section'])
+{
+ case 'main' :
+ {
+
+ function order_by_is_local()
+ {
+ $conf = array();
+ include(PHPWG_ROOT_PATH . 'include/config_default.inc.php');
+ @include(PHPWG_ROOT_PATH. 'local/config/config.inc.php');
+ if (isset($conf['local_dir_site']))
+ {
+ @include(PHPWG_ROOT_PATH.PWG_LOCAL_DIR. 'config/config.inc.php');
+ }
+
+ return isset($conf['order_by']) or isset($conf['order_by_inside_category']);
+ }
+
+ if (order_by_is_local())
+ {
+ $page['warnings'][] = l10n('You have specified $conf[\'order_by\'] in your local configuration file, this parameter in deprecated, please remove it or rename it into $conf[\'order_by_custom\'] !');
+ }
+
+ if ( isset($conf['order_by_custom']) or isset($conf['order_by_inside_category_custom']) )
+ {
+ $order_by = array('');
+ $template->assign('ORDER_BY_IS_CUSTOM', true);
+ }
+ else
+ {
+ $out = array();
+ $order_by = trim($conf['order_by_inside_category']);
+ $order_by = str_replace('ORDER BY ', false, $order_by);
+ $order_by = explode(', ', $order_by);
+ }
+
+ $template->assign(
+ 'main',
+ array(
+ 'CONF_GALLERY_TITLE' => htmlspecialchars($conf['gallery_title']),
+ 'CONF_PAGE_BANNER' => htmlspecialchars($conf['page_banner']),
+ 'week_starts_on_options' => array(
+ 'sunday' => $lang['day'][0],
+ 'monday' => $lang['day'][1],
+ ),
+ 'week_starts_on_options_selected' => $conf['week_starts_on'],
+ 'mail_theme' => $conf['mail_theme'],
+ 'mail_theme_options' => $mail_themes,
+ 'order_by' => $order_by,
+ 'order_by_options' => $sort_fields,
+ 'email_admin_on_new_user' => 'none' != $conf['email_admin_on_new_user'],
+ 'email_admin_on_new_user_filter' => in_array($conf['email_admin_on_new_user'], array('none', 'all')) ? 'all' : 'group',
+ 'email_admin_on_new_user_filter_group' => preg_match('/^group:(\d+)$/', $conf['email_admin_on_new_user'], $matches) ? $matches[1] : -1,
+ )
+ );
+
+ // list of groups
+ $query = '
+ SELECT
+ id,
+ name
+ FROM `'.GROUPS_TABLE.'`
+ ;';
+ $groups = query2array($query, 'id', 'name');
+ natcasesort($groups);
+
+ $template->assign(
+ array(
+ 'group_options' => $groups,
+ )
+ );
+
+ foreach ($main_checkboxes as $checkbox)
+ {
+ $template->append(
+ 'main',
+ array(
+ $checkbox => $conf[$checkbox]
+ ),
+ true
+ );
+ }
+ break;
+ }
+ case 'comments' :
+ {
+ $template->assign(
+ 'comments',
+ array(
+ 'NB_COMMENTS_PAGE'=>$conf['nb_comment_page'],
+ 'comments_order'=>$conf['comments_order'],
+ 'comments_order_options'=> $comments_order
+ )
+ );
+
+ foreach ($comments_checkboxes as $checkbox)
+ {
+ $template->append(
+ 'comments',
+ array(
+ $checkbox => $conf[$checkbox]
+ ),
+ true
+ );
+ }
+ break;
+ }
+ case 'default' :
+ {
+ $edit_user = build_user($conf['guest_id'], false);
+ include_once(PHPWG_ROOT_PATH.'profile.php');
+
+ $errors = array();
+ if (save_profile_from_post($edit_user, $errors))
+ {
+ // Reload user
+ $edit_user = build_user($conf['guest_id'], false);
+ $page['infos'][] = l10n('Information data registered in database');
+ }
+ $page['errors'] = array_merge($page['errors'], $errors);
+
+ load_profile_in_template(
+ $action,
+ '',
+ $edit_user,
+ 'GUEST_'
+ );
+ $template->assign('default', array());
+ break;
+ }
+ case 'display' :
+ {
+ foreach ($display_checkboxes as $checkbox)
+ {
+ $template->append(
+ 'display',
+ array(
+ $checkbox => $conf[$checkbox]
+ ),
+ true
+ );
+ }
+ $template->append(
+ 'display',
+ array(
+ 'picture_informations' => unserialize($conf['picture_informations']),
+ 'NB_CATEGORIES_PAGE' => $conf['nb_categories_page'],
+ ),
+ true
+ );
+ break;
+ }
+ case 'sizes' :
+ {
+ // we only load the derivatives if it was not already loaded: it occurs
+ // when submitting the form and an error remains
+ if (!isset($page['sizes_loaded_in_tpl']))
+ {
+ $is_gd = (pwg_image::get_library()=='gd')? true : false;
+ $template->assign('is_gd', $is_gd);
+ $template->assign(
+ 'sizes',
+ array(
+ 'original_resize_maxwidth' => $conf['original_resize_maxwidth'],
+ 'original_resize_maxheight' => $conf['original_resize_maxheight'],
+ 'original_resize_quality' => $conf['original_resize_quality'],
+ )
+ );
+
+ foreach ($sizes_checkboxes as $checkbox)
+ {
+ $template->append(
+ 'sizes',
+ array(
+ $checkbox => $conf[$checkbox]
+ ),
+ true
+ );
+ }
+
+ // derivatives = multiple size
+ $enabled = ImageStdParams::get_defined_type_map();
+ $disabled = safe_unserialize(ImageStdParams::get_disabled_type_map());
+ if ($disabled === false)
+ {
+ $disabled = array();
+ }
+
+ $tpl_vars = array();
+ foreach(ImageStdParams::get_all_types() as $type)
+ {
+ $tpl_var = array();
+
+ $tpl_var['must_square'] = ($type==IMG_SQUARE ? true : false);
+ $tpl_var['must_enable'] = ($type==IMG_SQUARE || $type==IMG_THUMB || $type==$conf['derivative_default_size'])? true : false;
+
+ if ($params = @$enabled[$type])
+ {
+ $tpl_var['enabled'] = true;
+ }
+ else
+ {
+ $tpl_var['enabled']=false;
+ $params=@$disabled[$type];
+ }
+
+ if ($params)
+ {
+ list($tpl_var['w'],$tpl_var['h']) = $params->sizing->ideal_size;
+ if ( ($tpl_var['crop'] = round(100*$params->sizing->max_crop)) > 0)
+ {
+ list($tpl_var['minw'],$tpl_var['minh']) = $params->sizing->min_size;
+ }
+ else
+ {
+ $tpl_var['minw'] = $tpl_var['minh'] = "";
+ }
+ $tpl_var['sharpen'] = $params->sharpen;
+ }
+ $tpl_vars[$type]=$tpl_var;
+ }
+ $template->assign('derivatives', $tpl_vars);
+ $template->assign('resize_quality', ImageStdParams::$quality);
+
+ $tpl_vars = array();
+ $now = time();
+ foreach(ImageStdParams::$custom as $custom=>$time)
+ {
+ $tpl_vars[$custom] = ($now-$time<=24*3600) ? l10n('today') : time_since($time, 'day');
+ }
+ $template->assign('custom_derivatives', $tpl_vars);
+ }
+
+ break;
+ }
+ case 'watermark' :
+ {
+ $watermark_files = array();
+ foreach (glob(PHPWG_ROOT_PATH.'themes/default/watermarks/*.png') as $file)
+ {
+ $watermark_files[] = substr($file, strlen(PHPWG_ROOT_PATH));
+ }
+ if ( ($glob=glob(PHPWG_ROOT_PATH.PWG_LOCAL_DIR.'watermarks/*.png')) !== false)
+ {
+ foreach ($glob as $file)
+ {
+ $watermark_files[] = substr($file, strlen(PHPWG_ROOT_PATH));
+ }
+ }
+ $watermark_filemap = array( '' => '---' );
+ foreach( $watermark_files as $file)
+ {
+ $display = basename($file);
+ $watermark_filemap[$file] = $display;
+ }
+ $template->assign('watermark_files', $watermark_filemap);
+
+ if ($template->get_template_vars('watermark') === null)
+ {
+ $wm = ImageStdParams::get_watermark();
+
+ $position = 'custom';
+ if ($wm->xpos == 0 and $wm->ypos == 0)
+ {
+ $position = 'topleft';
+ }
+ if ($wm->xpos == 100 and $wm->ypos == 0)
+ {
+ $position = 'topright';
+ }
+ if ($wm->xpos == 50 and $wm->ypos == 50)
+ {
+ $position = 'middle';
+ }
+ if ($wm->xpos == 0 and $wm->ypos == 100)
+ {
+ $position = 'bottomleft';
+ }
+ if ($wm->xpos == 100 and $wm->ypos == 100)
+ {
+ $position = 'bottomright';
+ }
+
+ if ($wm->xrepeat != 0 || $wm->yrepeat != 0)
+ {
+ $position = 'custom';
+ }
+
+ $template->assign(
+ 'watermark',
+ array(
+ 'file' => $wm->file,
+ 'minw' => $wm->min_size[0],
+ 'minh' => $wm->min_size[1],
+ 'xpos' => $wm->xpos,
+ 'ypos' => $wm->ypos,
+ 'xrepeat' => $wm->xrepeat,
+ 'yrepeat' => $wm->yrepeat,
+ 'opacity' => $wm->opacity,
+ 'position' => $position,
+ )
+ );
+ }
+
+ break;
+ }
+ case 'search':
+ {
+ $template->assign(
+ 'search',
+ array(
+ 'filters_views' => safe_unserialize($conf['filters_views']),
+ 'filters_names' => $filters_names_checkboxes,
+ ),
+ );
+ $template->assign('SHOW_FILTER_RATINGS', $conf['rate']);
+ }
+}
+
+$template->assign('isWebmaster', (is_webmaster()) ? 1 : 0);
+$template->assign('ADMIN_PAGE_TITLE', l10n('Configuration'));
+
+//----------------------------------------------------------- sending html code
+$template->assign_var_from_handle('ADMIN_CONTENT', 'config');
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/element_set_ranks.php b/Piwingo/piwigo-data/piwigo/admin/element_set_ranks.php
new file mode 100644
index 0000000..b2128c5
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/element_set_ranks.php
@@ -0,0 +1,234 @@
+assign(
+ array(
+ 'save_success' => $message,
+ )
+ );
+}
+
+// +-----------------------------------------------------------------------+
+// | template init |
+// +-----------------------------------------------------------------------+
+$template->set_filenames(
+ array('element_set_ranks' => 'element_set_ranks.tpl')
+ );
+
+$base_url = get_root_url().'admin.php';
+
+$query = '
+SELECT *
+ FROM '.CATEGORIES_TABLE.'
+ WHERE id = '.$page['category_id'].'
+;';
+$category = pwg_db_fetch_assoc(pwg_query($query));
+
+if ($category['image_order']=='rank ASC' or $category['image_order']=='`rank` ASC')
+{
+ $image_order_choice = 'rank';
+}
+elseif ($category['image_order']!='')
+{
+ $image_order_choice = 'user_define';
+}
+
+// Navigation path
+$navigation = get_cat_display_name_cache(
+ $category['uppercats'],
+ get_root_url().'admin.php?page=album-'
+ );
+
+$template->assign(
+ array(
+ 'CATEGORIES_NAV' => preg_replace("# {2,}#"," ",preg_replace("#(\r\n|\n\r|\n|\r)#"," ",$navigation)),
+ 'F_ACTION' => $base_url.get_query_string_diff(array()),
+ )
+ );
+
+// +-----------------------------------------------------------------------+
+// | thumbnails |
+// +-----------------------------------------------------------------------+
+
+$query = '
+SELECT
+ id,
+ file,
+ path,
+ representative_ext,
+ width, height, rotation,
+ name,
+ `rank`
+ FROM '.IMAGES_TABLE.'
+ JOIN '.IMAGE_CATEGORY_TABLE.' ON image_id = id
+ WHERE category_id = '.$page['category_id'].'
+ ORDER BY `rank`
+;';
+$result = pwg_query($query);
+if (pwg_db_num_rows($result) > 0)
+{
+ // template thumbnail initialization
+ $current_rank = 1;
+ $derivativeParams = ImageStdParams::get_by_type(IMG_SQUARE);
+ while ($row = pwg_db_fetch_assoc($result))
+ {
+ $derivative = new DerivativeImage($derivativeParams, new SrcImage($row));
+
+ if ( !empty( $row['name'] ) )
+ {
+ $thumbnail_name = $row['name'];
+ }
+ else
+ {
+ $file_wo_ext = get_filename_wo_extension($row['file']);
+ $thumbnail_name = str_replace('_', ' ', $file_wo_ext);
+ }
+ $current_rank++;
+ $template->append(
+ 'thumbnails',
+ array(
+ 'ID' => $row['id'],
+ 'NAME' => $thumbnail_name,
+ 'TN_SRC' => $derivative->get_url(),
+ 'RANK' => $current_rank * 10,
+ 'SIZE' => $derivative->get_size(),
+ )
+ );
+ }
+}
+// image order management
+$sort_fields = array(
+ '' => '',
+ 'file ASC' => l10n('File name, A → Z'),
+ 'file DESC' => l10n('File name, Z → A'),
+ 'name ASC' => l10n('Photo title, A → Z'),
+ 'name DESC' => l10n('Photo title, Z → A'),
+ 'date_creation DESC' => l10n('Date created, new → old'),
+ 'date_creation ASC' => l10n('Date created, old → new'),
+ 'date_available DESC' => l10n('Date posted, new → old'),
+ 'date_available ASC' => l10n('Date posted, old → new'),
+ 'rating_score DESC' => l10n('Rating score, high → low'),
+ 'rating_score ASC' => l10n('Rating score, low → high'),
+ 'hit DESC' => l10n('Visits, high → low'),
+ 'hit ASC' => l10n('Visits, low → high'),
+ 'id ASC' => l10n('Numeric identifier, 1 → 9'),
+ 'id DESC' => l10n('Numeric identifier, 9 → 1'),
+ 'rank ASC' => l10n('Manual sort order'),
+ );
+
+$template->assign('image_order_options', $sort_fields);
+
+$image_order = explode(',', isset($category['image_order']) ? $category['image_order'] : "");
+
+for ($i=0; $i<3; $i++) // 3 fields
+{
+ if ( isset($image_order[$i]) )
+ {
+ $template->append('image_order', $image_order[$i]);
+ }
+ else
+ {
+ $template->append('image_order', '');
+ }
+}
+
+$template->assign('image_order_choice', $image_order_choice);
+
+
+// +-----------------------------------------------------------------------+
+// | sending html code |
+// +-----------------------------------------------------------------------+
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'element_set_ranks');
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/extend_for_templates.php b/Piwingo/piwigo-data/piwigo/admin/extend_for_templates.php
new file mode 100644
index 0000000..e771170
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/extend_for_templates.php
@@ -0,0 +1,189 @@
+ Random */
+ 'tags',
+ );
+ $query = '
+SELECT permalink
+ FROM '.CATEGORIES_TABLE.'
+ WHERE permalink IS NOT NULL
+';
+
+/* Add active permalinks */
+$permalinks = array_from_query($query, 'permalink');
+$relevant_parameters = array_merge($relevant_parameters, $permalinks);
+
+/* Link all supported templates to their respective handle */
+$eligible_templates = array(
+ '----------' => 'N/A',
+ 'about.tpl' => 'about',
+ 'comments.tpl' => 'comments',
+ 'comment_list.tpl' => 'comment_list',
+ 'footer.tpl' => 'tail',
+ 'header.tpl' => 'header',
+ 'identification.tpl' => 'identification',
+ 'index.tpl' => 'index',
+ 'mainpage_categories.tpl' => 'index_category_thumbnails',
+ 'menubar.tpl' => 'menubar',
+ 'menubar_categories.tpl' => 'mbCategories',
+ 'menubar_identification.tpl' => 'mbIdentification',
+ 'menubar_links.tpl' => 'mbLinks',
+ 'menubar_menu.tpl' => 'mbMenu',
+ 'menubar_specials.tpl' => 'mbSpecials',
+ 'menubar_tags.tpl' => 'mbTags',
+ 'month_calendar.tpl' => 'month_calendar',
+ 'navigation_bar.tpl' => 'navbar',
+ 'nbm.tpl' => 'nbm',
+ 'notification.tpl' => 'notification',
+ 'password.tpl' => 'password',
+ 'picture.tpl' => 'picture',
+ 'picture_content.tpl' => 'default_content',
+ 'picture_nav_buttons.tpl' => 'picture_nav_buttons',
+ 'popuphelp.tpl' => 'popuphelp',
+ 'profile.tpl' => 'profile',
+ 'profile_content.tpl' => 'profile_content',
+ 'redirect.tpl' => 'redirect',
+ 'register.tpl' => 'register',
+ 'search.tpl' => 'search',
+ 'slideshow.tpl' => 'slideshow',
+ 'tags.tpl' => 'tags',
+ 'thumbnails.tpl' => 'index_thumbnails',
+);
+
+$flip_templates = array_flip($eligible_templates);
+
+$available_templates = array_merge(
+ array('N/A' => '----------'),
+ get_dirs(PHPWG_ROOT_PATH.'themes'));
+
+// +-----------------------------------------------------------------------+
+// | selected templates |
+// +-----------------------------------------------------------------------+
+
+if (isset($_POST['submit']))
+{
+ $replacements = array();
+ $i = 0;
+ while (isset($_POST['reptpl'][$i]))
+ {
+ $newtpl = $_POST['reptpl'][$i];
+ $original = $_POST['original'][$i];
+ $handle = $eligible_templates[$original];
+ $url_keyword = $_POST['url'][$i];
+ if ($url_keyword == '----------') $url_keyword = 'N/A';
+ $bound_tpl = $_POST['bound'][$i];
+ if ($bound_tpl == '----------') $bound_tpl = 'N/A';
+ if ($handle != 'N/A')
+ {
+ $replacements[$newtpl] = array($handle, $url_keyword, $bound_tpl);
+ }
+ $i++;
+ }
+ $conf['extents_for_templates'] = serialize($replacements);
+ $tpl_extension = $replacements;
+ /* ecrire la nouvelle conf */
+ $query = '
+UPDATE '.CONFIG_TABLE.'
+ SET value = \''. $conf['extents_for_templates'] .'\'
+WHERE param = \'extents_for_templates\';';
+ if (pwg_query($query))
+ {
+ $page['infos'][] = l10n('Templates configuration has been recorded.');
+ }
+}
+
+// +-----------------------------------------------------------------------+
+// | template init |
+// +-----------------------------------------------------------------------+
+
+/* Clearing (remove old extents, add new ones) */
+foreach ($tpl_extension as $file => $conditions)
+{
+ if ( !in_array($file,$new_extensions) ) unset($tpl_extension[$file]);
+ else $new_extensions = array_diff($new_extensions,array($file));
+}
+foreach ($new_extensions as $file)
+{
+ $tpl_extension[$file] = array('N/A', 'N/A', 'N/A');
+}
+
+$template->set_filenames(array('extend_for_templates'
+ => 'extend_for_templates.tpl'));
+
+$base_url = PHPWG_ROOT_PATH.'admin.php?page=extend_for_templates';
+
+$template->assign(
+ array(
+ 'U_HELP' => get_root_url().'admin/popuphelp.php?page=extend_for_templates',
+ ));
+ksort($tpl_extension);
+foreach ($tpl_extension as $file => $conditions)
+{
+ $handle = $conditions[0];
+ $url_keyword = $conditions[1];
+ $bound_tpl = $conditions[2];
+ {
+ $template->append('extents',
+ array(
+ 'replacer' => $file,
+ 'url_parameter' => $relevant_parameters,
+ 'original_tpl' => array_keys($eligible_templates),
+ 'bound_tpl' => $available_templates,
+ 'selected_tpl' => $flip_templates[$handle],
+ 'selected_url' => $url_keyword,
+ 'selected_bound' => $bound_tpl,)
+ );
+ }
+}
+// +-----------------------------------------------------------------------+
+// | html code display |
+// +-----------------------------------------------------------------------+
+$template->assign('ADMIN_PAGE_TITLE', l10n('Extend for templates'));
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'extend_for_templates');
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/group_list.php b/Piwingo/piwigo-data/piwigo/admin/group_list.php
new file mode 100644
index 0000000..1cdcde2
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/group_list.php
@@ -0,0 +1,116 @@
+set_id('groups');
+$tabsheet->select('group_list');
+$tabsheet->assign();
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok |
+// +-----------------------------------------------------------------------+
+check_status(ACCESS_ADMINISTRATOR);
+
+if (!empty($_POST) or isset($_GET['delete']) or isset($_GET['toggle_is_default']))
+{
+ check_pwg_token();
+}
+
+
+// +-----------------------------------------------------------------------+
+// | template init |
+// +-----------------------------------------------------------------------+
+
+$template->set_filenames(array('group_list' => 'group_list.tpl'));
+
+$template->assign(
+ array(
+ 'F_ADD_ACTION' => get_root_url().'admin.php?page=group_list',
+ // 'U_HELP' => get_root_url().'admin/popuphelp.php?page=group_list',
+ 'PWG_TOKEN' => get_pwg_token(),
+ 'CACHE_KEYS' => get_admin_client_cache_keys(array('groups', 'users')),
+ )
+ );
+
+// +-----------------------------------------------------------------------+
+// | group list |
+// +-----------------------------------------------------------------------+
+
+$query = '
+SELECT id, name, is_default
+ FROM `'.GROUPS_TABLE.'`
+ ORDER BY name ASC
+;';
+$result = pwg_query($query);
+
+$admin_url = get_root_url().'admin.php?page=';
+$perm_url = $admin_url.'group_perm&group_id=';
+$users_url = $admin_url.'user_list&group=';
+$del_url = $admin_url.'group_list&delete=';
+$toggle_is_default_url = $admin_url.'group_list&toggle_is_default=';
+
+$group_counter = 0;
+
+while ($row = pwg_db_fetch_assoc($result))
+{
+ $query = '
+SELECT u.'. $conf['user_fields']['username'].' AS username
+ FROM '.USERS_TABLE.' AS u
+ INNER JOIN '.USER_GROUP_TABLE.' AS ug
+ ON u.'.$conf['user_fields']['id'].' = ug.user_id
+ WHERE ug.group_id = '.$row['id'].'
+;';
+ $members=array();
+ $res=pwg_query($query);
+ while ($us= pwg_db_fetch_assoc($res))
+ {
+ $members[]=$us['username'];
+ }
+ $template->append(
+ 'groups',
+ array(
+ 'NAME' => $row['name'],
+ 'ID' => $row['id'],
+ 'IS_DEFAULT' => (get_boolean($row['is_default']) ? ' ['.l10n('default').']' : ''),
+ 'NB_MEMBERS' => count($members),
+ 'L_MEMBERS' => implode(' · ', $members),
+ 'MEMBERS' => l10n_dec('%d member', '%d members', count($members)),
+ 'U_DELETE' => $del_url.$row['id'].'&pwg_token='.get_pwg_token(),
+ 'U_PERM' => $perm_url.$row['id'],
+ 'U_USERS' => $users_url.$row['id'],
+ 'U_ISDEFAULT' => $toggle_is_default_url.$row['id'].'&pwg_token='.get_pwg_token(),
+ )
+ );
+
+ $group_counter++;
+}
+
+$template->assign('ADMIN_PAGE_TITLE', l10n('Groups').' '.$group_counter.'');
+
+// +-----------------------------------------------------------------------+
+// | sending html code |
+// +-----------------------------------------------------------------------+
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'group_list');
+
+?>
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/group_perm.php b/Piwingo/piwigo-data/piwigo/admin/group_perm.php
new file mode 100644
index 0000000..079831d
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/group_perm.php
@@ -0,0 +1,176 @@
+ 0)
+{
+ // if you forbid access to a category, all sub-categories become
+ // automatically forbidden
+ $subcats = get_subcat_ids($_POST['cat_true']);
+ $query = '
+DELETE
+ FROM '.GROUP_ACCESS_TABLE.'
+ WHERE group_id = '.$page['group'].'
+ AND cat_id IN ('.implode(',', $subcats).')
+;';
+ pwg_query($query);
+}
+else if (isset($_POST['trueify'])
+ and isset($_POST['cat_false'])
+ and count($_POST['cat_false']) > 0)
+{
+ $uppercats = get_uppercat_ids($_POST['cat_false']);
+ $private_uppercats = array();
+
+ $query = '
+SELECT id
+ FROM '.CATEGORIES_TABLE.'
+ WHERE id IN ('.implode(',', $uppercats).')
+ AND status = \'private\'
+;';
+ $result = pwg_query($query);
+ while ($row = pwg_db_fetch_assoc($result))
+ {
+ $private_uppercats[] = $row['id'];
+ }
+
+ // retrying to authorize a category which is already authorized may cause
+ // an error (in SQL statement), so we need to know which categories are
+ // accesible
+ $authorized_ids = array();
+
+ $query = '
+SELECT cat_id
+ FROM '.GROUP_ACCESS_TABLE.'
+ WHERE group_id = '.$page['group'].'
+;';
+ $result = pwg_query($query);
+
+ while ($row = pwg_db_fetch_assoc($result))
+ {
+ $authorized_ids[] = $row['cat_id'];
+ }
+
+ $inserts = array();
+ $to_autorize_ids = array_diff($private_uppercats, $authorized_ids);
+ foreach ($to_autorize_ids as $to_autorize_id)
+ {
+ $inserts[] = array(
+ 'group_id' => $page['group'],
+ 'cat_id' => $to_autorize_id
+ );
+ }
+
+ mass_inserts(GROUP_ACCESS_TABLE, array('group_id','cat_id'), $inserts);
+ invalidate_user_cache();
+}
+
+// +-----------------------------------------------------------------------+
+// | template init |
+// +-----------------------------------------------------------------------+
+
+$template->set_filenames(
+ array(
+ 'group_perm' => 'group_perm.tpl',
+ 'double_select' => 'double_select.tpl'
+ )
+ );
+
+$template->assign(
+ array(
+ 'TITLE' =>
+ l10n(
+ 'Manage permissions for group "%s"',
+ get_groupname($page['group'])
+ ),
+ 'L_CAT_OPTIONS_TRUE'=>l10n('Authorized'),
+ 'L_CAT_OPTIONS_FALSE'=>l10n('Forbidden'),
+
+ 'F_ACTION' =>
+ get_root_url().
+ 'admin.php?page=group_perm&group_id='.
+ $page['group']
+ )
+ );
+
+// only private categories are listed
+$query_true = '
+SELECT id,name,uppercats,global_rank
+ FROM '.CATEGORIES_TABLE.' INNER JOIN '.GROUP_ACCESS_TABLE.' ON cat_id = id
+ WHERE status = \'private\'
+ AND group_id = '.$page['group'].'
+;';
+display_select_cat_wrapper($query_true,array(),'category_option_true');
+
+$result = pwg_query($query_true);
+$authorized_ids = array();
+while ($row = pwg_db_fetch_assoc($result))
+{
+ $authorized_ids[] = $row['id'];
+}
+
+$query_false = '
+SELECT id,name,uppercats,global_rank
+ FROM '.CATEGORIES_TABLE.'
+ WHERE status = \'private\'';
+if (count($authorized_ids) > 0)
+{
+ $query_false.= '
+ AND id NOT IN ('.implode(',', $authorized_ids).')';
+}
+$query_false.= '
+;';
+display_select_cat_wrapper($query_false,array(),'category_option_false');
+
+$template->assign('PWG_TOKEN', get_pwg_token());
+
+// +-----------------------------------------------------------------------+
+// | html code display |
+// +-----------------------------------------------------------------------+
+
+$template->assign_var_from_handle('DOUBLE_SELECT', 'double_select');
+$template->assign_var_from_handle('ADMIN_CONTENT', 'group_perm');
+
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/help.php b/Piwingo/piwigo-data/piwigo/admin/help.php
new file mode 100644
index 0000000..03b3bc8
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/help.php
@@ -0,0 +1,70 @@
+set_id('help');
+$tabsheet->select($selected);
+$tabsheet->assign();
+
+trigger_notify('loc_end_help');
+
+$template->set_filenames(array('help' => 'help.tpl'));
+
+$template->assign(
+ array(
+ 'HELP_CONTENT' => load_language(
+ 'help/help_'.$tabsheet->selected.'.html',
+ '',
+ array('return'=>true)
+ ),
+ 'HELP_SECTION_TITLE' => $tabsheet->sheets[ $tabsheet->selected ]['caption'],
+ )
+ );
+
+$language_prefix = substr($user['language'], 0, 3);
+if ('en_' == $language_prefix)
+{
+ $page['messages'][] = sprintf(
+ 'Need help to use Piwigo? Check the online documentation !',
+ 'https://doc.piwigo.org/'
+ );
+}
+elseif ('fr_' == $language_prefix)
+{
+ $page['messages'][] = sprintf(
+ 'Besoin d\'aide pour utiliser Piwigo ? Consultez la documentation en ligne !',
+ 'https://doc-fr.piwigo.org/'
+ );
+}
+
+// +-----------------------------------------------------------------------+
+// | sending html code |
+// +-----------------------------------------------------------------------+
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'help');
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/history.php b/Piwingo/piwigo-data/piwigo/admin/history.php
new file mode 100644
index 0000000..075ad92
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/history.php
@@ -0,0 +1,150 @@
+ l10n('No display'),
+ 'display_thumbnail_classic' => l10n('Classic display'),
+ 'display_thumbnail_hoverbox' => l10n('Hoverbox display')
+ );
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok |
+// +-----------------------------------------------------------------------+
+
+check_status(ACCESS_ADMINISTRATOR);
+
+check_input_parameter('filter_ip', $_GET, false, '/^[0-9.]+$/');
+check_input_parameter('filter_image_id', $_GET, false, '/^\d+$/');
+check_input_parameter('filter_user_id', $_GET, false, '/^\d+$/');
+
+// +-----------------------------------------------------------------------+
+// | template init |
+// +-----------------------------------------------------------------------+
+
+$template->set_filename('history', 'history.tpl');
+
+// TabSheet initialization
+history_tabsheet();
+
+$template->assign(
+ array(
+ 'F_ACTION' => get_root_url().'admin.php?page=history',
+ 'API_METHOD' => 'ws.php?format=json&method=pwg.history.search'
+ )
+ );
+
+// +-----------------------------------------------------------------------+
+// | navigation bar |
+// +-----------------------------------------------------------------------+
+
+if (isset($page['search_id']))
+{
+ $navbar = create_navigation_bar(
+ get_root_url().'admin.php'.get_query_string_diff(array('start')),
+ $page['nb_lines'],
+ $page['start'],
+ $conf['nb_logs_page']
+ );
+
+ $template->assign('navbar', $navbar);
+}
+
+// +-----------------------------------------------------------------------+
+// | filter form |
+// +-----------------------------------------------------------------------+
+
+$form = array();
+
+if (isset($page['search']))
+{
+ if (isset($page['search']['fields']['date-after']))
+ {
+ $form['start'] = $page['search']['fields']['date-after'];
+ }
+
+ if (isset($page['search']['fields']['date-before']))
+ {
+ $form['end'] = $page['search']['fields']['date-before'];
+ }
+}
+else
+{
+ // by default, at page load, we want the selected date to be the current
+ // date
+ $form['start'] = $form['end'] = date('Y-m-d');
+ $form['types'] = $types;
+ // Hoverbox by default
+ $form['display_thumbnail'] =
+ pwg_get_cookie_var('display_thumbnail', 'no_display_thumbnail');
+}
+
+$form_param['ip'] = isset($_GET['filter_ip']) ? $_GET['filter_ip'] : @$form['ip'];
+$form_param['image_id'] = isset($_GET['filter_image_id']) ? $_GET['filter_image_id'] : @$form['image_id'];
+$form_param['user_id'] = isset($_GET['filter_user_id']) ? $_GET['filter_user_id'] : "-1";
+
+if (isset($_GET['filter_ip']) or isset($_GET['filter_image_id']) or isset($_GET['filter_user_id']))
+{
+ $form['start'] = '';
+}
+
+if ($form_param['user_id'] != "-1") {
+ $query = '
+ SELECT
+ username
+ FROM '.USERS_TABLE.'
+ WHERE id = '.$form_param['user_id'].'
+ ;';
+
+ list($form_param['user_name']) = pwg_db_fetch_row(pwg_query($query));
+ $form_param['user_id'] = empty(pwg_db_fetch_row(pwg_query($query))) ? "-1" : $form_param['user_id'];
+}
+
+$template->assign(
+ array(
+ 'USER_ID' => $form_param['user_id'],
+ 'USER_NAME' => @$form_param['user_name'],
+ 'IMAGE_ID' => $form_param['image_id'],
+ 'FILENAME' => @$form['filename'],
+ 'IP' => $form_param['ip'],
+ 'START' => @$form['start'],
+ 'END' => @$form['end'],
+ )
+ );
+
+$template->assign('display_thumbnails', $display_thumbnails);
+$template->assign('display_thumbnail_selected', $form['display_thumbnail']);
+$template->assign('guest_id', $conf['guest_id']);
+$template->assign('ADMIN_PAGE_TITLE', l10n('History'));
+
+// +-----------------------------------------------------------------------+
+// | html code display |
+// +-----------------------------------------------------------------------+
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'history');
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/include/add_core_tabs.inc.php b/Piwingo/piwigo-data/piwigo/admin/include/add_core_tabs.inc.php
new file mode 100644
index 0000000..11a2788
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/include/add_core_tabs.inc.php
@@ -0,0 +1,197 @@
+ l10n('Administration Home'), 'url' => 'admin.php');
+ break;
+
+ case 'tags':
+ global $my_base_url;
+ $sheets[''] = array('caption' => ''.l10n('List'), 'url' => $my_base_url.'tags');
+ break;
+
+ case 'album':
+ global $admin_album_base_url;
+ $sheets['properties'] = array('caption' => ''.l10n('Properties'), 'url' => $admin_album_base_url.'-properties');
+ $sheets['sort_order'] = array('caption' => ''.l10n('Manage photo ranks'), 'url' => $admin_album_base_url.'-sort_order');
+ $sheets['permissions'] = array('caption' => ''.l10n('Permissions'), 'url' => $admin_album_base_url.'-permissions');
+ $sheets['notification'] = array('caption' => ''.l10n('Notification'), 'url' => $admin_album_base_url.'-notification');
+ break;
+
+ case 'albums':
+ global $my_base_url;
+ $sheets['list'] = array('caption' => ''.l10n('List'), 'url' => $my_base_url.'albums');
+ $sheets['permalinks'] = array('caption' => ''.l10n('Permalinks'), 'url' => $my_base_url.'permalinks');
+ break;
+
+ case 'users':
+ global $my_base_url;
+ $sheets['user_list'] = array('caption' => ''.l10n('List'), 'url' => $my_base_url.'user_list');
+ $sheets['user_activity'] = array('caption' => ''.l10n('Activity'), 'url' => $my_base_url.'user_activity');
+ break;
+
+ case 'batch_manager':
+ global $manager_link;
+ $sheets['global'] = array('caption' => ''.l10n('global mode'), 'url' => $manager_link.'global');
+ $sheets['unit'] = array('caption' => ''.l10n('unit mode'), 'url' => $manager_link.'unit');
+ break;
+
+ case 'cat_options':
+ global $link_start;
+ $sheets['status'] = array('caption' => ''.l10n('Public / Private'), 'url' => $link_start.'cat_options§ion=status');
+ $sheets['visible'] = array('caption' => ''.l10n('Lock'), 'url' => $link_start.'cat_options§ion=visible');
+ if ($conf['activate_comments'])
+ $sheets['comments'] = array('caption' => ''.l10n('Comments'), 'url' => $link_start.'cat_options§ion=comments');
+ if ($conf['allow_random_representative'])
+ $sheets['representative'] = array('caption' => l10n('Representative'), 'url' => $link_start.'cat_options§ion=representative');
+ break;
+
+ case 'comments':
+ global $my_base_url;
+ $sheets[''] = array('caption' => ''.l10n('List'), 'url' => $my_base_url.'comments');
+ break;
+
+ case 'users':
+ global $my_base_url;
+ $sheets[''] = array('caption' => ' '.l10n('User list'), 'url' => $my_base_url.'user_list');
+ break;
+
+ case 'groups':
+ global $my_base_url;
+ $sheets[''] = array('caption' => ''.l10n('List'), 'url' => $my_base_url.'group_list');
+ break;
+
+ case 'configuration':
+ global $conf_link;
+ $sheets['main'] = array('caption' => ''.l10n('General'), 'url' => $conf_link.'main');
+ $sheets['sizes'] = array('caption' => ''.l10n('Photo sizes'), 'url' => $conf_link.'sizes');
+ $sheets['watermark'] = array('caption' => ''.l10n('Watermark'), 'url' => $conf_link.'watermark');
+ $sheets['display'] = array('caption' => ''.l10n('Display'), 'url' => $conf_link.'display');
+ $sheets['comments'] = array('caption' => ''.l10n('Comments'), 'url' => $conf_link.'comments');
+ $sheets['search'] = array('caption' => ''.l10n('Search'), 'url' => $conf_link.'search');
+ // $sheets['default'] = array('caption' => l10n('Guest Settings'), 'url' => $conf_link.'default');
+ break;
+
+ case 'help':
+ global $help_link;
+ $sheets['add_photos'] = array('caption' => l10n('Add Photos'), 'url' => $help_link.'add_photos');
+ $sheets['permissions'] = array('caption' => l10n('Permissions'), 'url' => $help_link.'permissions');
+ $sheets['groups'] = array('caption' => l10n('Groups'), 'url' => $help_link.'groups');
+ $sheets['virtual_links'] = array('caption' => l10n('Virtual Links'), 'url' => $help_link.'virtual_links');
+ $sheets['misc'] = array('caption' => l10n('Miscellaneous'), 'url' => $help_link.'misc');
+ break;
+
+ case 'history':
+ global $link_start;
+ $sheets['stats'] = array('caption' => ''.l10n('Statistics'), 'url' => $link_start.'stats');
+ $sheets['history'] = array('caption' => ''.l10n('Search'), 'url' => $link_start.'history');
+ break;
+
+ case 'languages':
+ global $my_base_url;
+ $sheets['installed'] = array('caption' => ''.l10n('List'), 'url' => $my_base_url.'&tab=installed');
+ if ($conf['enable_extensions_install'])
+ {
+ $sheets['update'] = array('caption' => ''.l10n('Check for updates'), 'url' => $my_base_url.'&tab=update');
+ $sheets['new'] = array('caption' => ''.l10n('Add New Language'), 'url' => $my_base_url.'&tab=new');
+ }
+ break;
+
+ case 'menus':
+ global $my_base_url;
+ $sheets[''] = array('caption' => ''.l10n('List'), 'url' => $my_base_url.'menubar');
+ break;
+
+ case 'nbm':
+ global $base_url;
+ $sheets['param'] = array('caption' => l10n('Parameter'), 'url' => $base_url.'?page=notification_by_mail&mode=param');
+ $sheets['subscribe'] = array('caption' => l10n('Subscribe'), 'url' => $base_url.'?page=notification_by_mail&mode=subscribe');
+ $sheets['send'] = array('caption' => l10n('Send'), 'url' => $base_url.'?page=notification_by_mail&mode=send');
+ break;
+
+ case 'photo':
+ global $admin_photo_base_url, $conf;
+ $sheets['properties'] = array('caption' => ''.l10n('Properties'), 'url' => $admin_photo_base_url.'-properties');
+ $sheets['coi'] = array('caption' => ''.l10n('Center of interest'), 'url' => $admin_photo_base_url.'-coi');
+ if ($conf['enable_formats'])
+ {
+ $sheets['formats'] = array('caption' => ''.l10n('Formats'), 'url' => $admin_photo_base_url.'-formats');
+ }
+ break;
+
+ case 'photos_add':
+ $sheets['direct'] = array('caption' => ''.l10n('Web Form'), 'url' => PHOTOS_ADD_BASE_URL.'§ion=direct');
+ $sheets['applications'] = array('caption' => ''.l10n('Applications'), 'url' => PHOTOS_ADD_BASE_URL.'§ion=applications');
+ if ($conf['enable_synchronization'])
+ $sheets['ftp'] = array('caption' => ''.l10n('FTP + Synchronization'), 'url' => PHOTOS_ADD_BASE_URL.'§ion=ftp');
+ break;
+
+ case 'plugins':
+ global $my_base_url;
+ $sheets['installed'] = array('caption' => ''.l10n('List'), 'url' => $my_base_url.'&tab=installed');
+ if ($conf['enable_extensions_install'])
+ {
+ $sheets['update'] = array('caption' => ''.l10n('Check for updates'), 'url' => $my_base_url.'&tab=update');
+ $sheets['new'] = array('caption' => ''.l10n('Add New Plugin'), 'url' => $my_base_url.'&tab=new');
+ }
+ break;
+
+ case 'rating':
+ $sheets['rating'] = array('caption' => l10n('Photos'), 'url' => get_root_url().'admin.php?page=rating');
+ $sheets['rating_user'] = array('caption' => l10n('Users'), 'url' => get_root_url().'admin.php?page=rating_user');
+ break;
+
+ case 'themes':
+ global $my_base_url;
+ $sheets['installed'] = array('caption' => ''.l10n('List'), 'url' => $my_base_url.'&tab=installed');
+ if ($conf['enable_extensions_install'])
+ {
+ $sheets['update'] = array('caption' => ''.l10n('Check for updates'), 'url' => $my_base_url.'&tab=update');
+ $sheets['new'] = array('caption' => ''.l10n('Add New Theme'), 'url' => $my_base_url.'&tab=new');
+ }
+ $sheets['standard_pages'] = array('caption' => ''.l10n('Standard pages'), 'url' => $my_base_url.'&tab=standard_pages');
+ break;
+
+ case 'updates':
+ global $my_base_url;
+
+ if ($conf['enable_core_update'])
+ {
+ $sheets['pwg'] = array('caption' => l10n('Piwigo core'), 'url' => $my_base_url);
+ }
+
+ if ($conf['enable_extensions_install'])
+ {
+ $sheets['ext'] = array('caption' => l10n('Extensions'), 'url' => $my_base_url.'&tab=ext');
+ }
+ break;
+ case 'site_update':
+ global $my_base_url;
+ $sheets['synchronization'] = array('caption' => ''.l10n('Synchronization'), 'url' => $my_base_url.'site_update&site=1');
+ $sheets['site_maager'] = array('caption' => ''.l10n('Site manager'), 'url' => $my_base_url.'site_manager');
+ break;
+ case 'maintenance':
+ global $my_base_url;
+ $sheets['actions'] = array('caption' => ''.l10n('Actions'), 'url' => $my_base_url.'maintenance&tab=actions');
+ $sheets['env'] = array('caption' => ''.l10n('Environment'), 'url' => $my_base_url.'maintenance&tab=env');
+ $sheets['sys'] = array('caption' => ''.l10n('System Activities'), 'url' => $my_base_url.'maintenance&tab=sys');
+ break;
+ }
+
+ return $sheets;
+}
+
+?>
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/include/albums_tab.inc.php b/Piwingo/piwigo-data/piwigo/admin/include/albums_tab.inc.php
new file mode 100644
index 0000000..46c949f
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/include/albums_tab.inc.php
@@ -0,0 +1,30 @@
+set_id('albums');
+$tabsheet->select($page['tab']);
+$tabsheet->assign();
+
+$query = '
+SELECT COUNT(*)
+ FROM '.CATEGORIES_TABLE.'
+;';
+
+list($nb_cats) = pwg_db_fetch_row(pwg_query($query));
+$template->assign(
+ array(
+ 'nb_cats' => $nb_cats,
+ )
+);
+
+?>
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/include/batch_manager_filters.inc.php b/Piwingo/piwigo-data/piwigo/admin/include/batch_manager_filters.inc.php
new file mode 100644
index 0000000..1481ffc
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/include/batch_manager_filters.inc.php
@@ -0,0 +1,141 @@
+ 'caddie', 'NAME' => l10n('Caddie')),
+ array('ID' => 'favorites', 'NAME' => l10n('Your favorites')),
+ array('ID' => 'last_import', 'NAME' => l10n('Last import')),
+ array('ID' => 'no_album', 'NAME' => l10n('With no album') . ' (' . l10n('Orphans') . ')'),
+ array('ID' => 'no_tag', 'NAME' => l10n('With no tag')),
+ array('ID' => 'duplicates', 'NAME' => l10n('Duplicates')),
+ array('ID' => 'all_photos', 'NAME' => l10n('All'))
+);
+
+if ($conf['enable_synchronization'])
+{
+ $prefilters[] = array('ID' => 'no_virtual_album', 'NAME' => l10n('With no virtual album'));
+ $prefilters[] = array('ID' => 'no_sync_md5sum', 'NAME' => l10n('With no checksum'));
+}
+
+function UC_name_compare($a, $b)
+{
+ return strcmp(strtolower($a['NAME']), strtolower($b['NAME']));
+}
+
+$prefilters = trigger_change('get_batch_manager_prefilters', $prefilters);
+
+// Sort prefilters by localized name.
+usort($prefilters, function ($a, $b) {
+ return strcmp(strtolower($a['NAME']), strtolower($b['NAME']));
+});
+
+$template->assign(
+ array(
+ 'conf_checksum_compute_blocksize' => $conf['checksum_compute_blocksize'],
+ 'prefilters' => $prefilters,
+ 'filter' => $_SESSION['bulk_manager_filter'],
+ 'selection' => $collection,
+ 'all_elements' => $page['cat_elements_id'],
+ 'START' => $page['start'],
+ 'PWG_TOKEN' => get_pwg_token(),
+ 'U_DISPLAY' => $base_url . get_query_string_diff(array('display')),
+ 'F_ACTION' => $base_url . get_query_string_diff(array('cat', 'start', 'tag', 'filter')),
+ 'ADMIN_PAGE_TITLE' => l10n('Batch Manager'),
+ )
+);
+
+if (isset($page['no_md5sum_number']))
+{
+ $template->assign(
+ array(
+ 'NB_NO_MD5SUM' => $page['no_md5sum_number'],
+ )
+ );
+} else {
+ $template->assign('NB_NO_MD5SUM', '');
+}
+
+// privacy level
+foreach ($conf['available_permission_levels'] as $level)
+{
+ $level_options[$level] = l10n(sprintf('Level %d', $level));
+
+ if (0 == $level) {
+ $level_options[$level] = l10n('Everybody');
+ }
+}
+$template->assign(
+ array(
+ 'filter_level_options' => $level_options,
+ 'filter_level_options_selected' => isset($_SESSION['bulk_manager_filter']['level'])
+ ? $_SESSION['bulk_manager_filter']['level']
+ : 0,
+ )
+);
+
+// tags
+$filter_tags = array();
+
+if (!empty($_SESSION['bulk_manager_filter']['tags']))
+{
+ $query = '
+SELECT
+ id,
+ name
+ FROM ' . TAGS_TABLE . '
+ WHERE id IN (' . implode(',', $_SESSION['bulk_manager_filter']['tags']) . ')
+;';
+
+ $filter_tags = get_taglist($query);
+}
+
+$template->assign('filter_tags', $filter_tags);
+
+// in the filter box, which category to select by default
+$selected_category = null;
+$selected_category_name = '';
+
+if (isset($_SESSION['bulk_manager_filter']['category']))
+{
+ $selected_category = intval($_SESSION['bulk_manager_filter']['category']);
+ $selected_category_name = get_cat_display_name_from_id($selected_category);
+}
+
+$template->assign('filter_category_selected_name', strip_tags($selected_category_name));
+$template->assign('filter_category_selected', $selected_category);
+
+// Dissociate from a category : categories listed for dissociation can only
+// represent virtual links. We can't create orphans. Links to physical
+// categories can't be broken.
+$associated_categories = array();
+
+if (count($page['cat_elements_id']) > 0)
+{
+ $query = '
+SELECT
+ DISTINCT(category_id) AS id
+ FROM ' . IMAGE_CATEGORY_TABLE . ' AS ic
+ JOIN ' . IMAGES_TABLE . ' AS i ON i.id = ic.image_id
+ WHERE ic.image_id IN (' . implode(',', $page['cat_elements_id']) . ')
+ AND (
+ ic.category_id != i.storage_category_id
+ OR i.storage_category_id IS NULL
+ )
+;';
+
+ $associated_categories = query2array($query, 'id', 'id');
+}
+
+$template->assign('associated_categories', $associated_categories);
+
+load_language('help_quick_search.lang');
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/include/c13y_internal.class.php b/Piwingo/piwigo-data/piwigo/admin/include/c13y_internal.class.php
new file mode 100644
index 0000000..d5d2dcb
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/include/c13y_internal.class.php
@@ -0,0 +1,243 @@
+ 'PHP',
+ 'current' => phpversion(),
+ 'required' => REQUIRED_PHP_VERSION,
+ );
+
+ $check_list[] = array(
+ 'type' => 'MySQL',
+ 'current' => pwg_get_db_version(),
+ 'required' => REQUIRED_MYSQL_VERSION,
+ );
+
+ foreach ($check_list as $elem)
+ {
+ if (version_compare($elem['current'], $elem['required'], '<'))
+ {
+ $c13y->add_anomaly(
+ sprintf(l10n('The version of %s [%s] installed is not compatible with the version required [%s]'), $elem['type'], $elem['current'], $elem['required']),
+ null,
+ null,
+ l10n('You need to upgrade your system to take full advantage of the application else the application will not work correctly, or not at all')
+ .'
'.
+ $c13y->get_htlm_links_more_info());
+ }
+ }
+ }
+
+ /**
+ * Check exif
+ *
+ * @param c13y object
+ * @return void
+ */
+ function c13y_exif($c13y)
+ {
+ global $conf;
+
+ foreach (array('show_exif', 'use_exif') as $value)
+ {
+ if (($conf[$value]) and (!function_exists('exif_read_data')))
+ {
+ $c13y->add_anomaly(
+ sprintf(l10n('%s value is not correct file because exif are not supported'), '$conf[\''.$value.'\']'),
+ null,
+ null,
+ sprintf(l10n('%s must be to set to false in your local/config/config.inc.php file'), '$conf[\''.$value.'\']')
+ .'
'.
+ $c13y->get_htlm_links_more_info());
+ }
+ }
+ }
+
+ /**
+ * Check user
+ *
+ * @param c13y object
+ * @return void
+ */
+ function c13y_user($c13y)
+ {
+ global $conf;
+
+ $c13y_users = array();
+ $c13y_users[$conf['guest_id']] = array(
+ 'status' => 'guest',
+ 'l10n_non_existent' => 'Main "guest" user does not exist',
+ 'l10n_bad_status' => 'Main "guest" user status is incorrect');
+
+ if ($conf['guest_id'] != $conf['default_user_id'])
+ {
+ $c13y_users[$conf['default_user_id']] = array(
+ 'password' => null,
+ 'l10n_non_existent' => 'Default user does not exist');
+ }
+
+ $c13y_users[$conf['webmaster_id']] = array(
+ 'status' => 'webmaster',
+ 'l10n_non_existent' => 'Main "webmaster" user does not exist',
+ 'l10n_bad_status' => 'Main "webmaster" user status is incorrect');
+
+ $query = '
+ select u.'.$conf['user_fields']['id'].' as id, ui.status
+ from '.USERS_TABLE.' as u
+ left join '.USER_INFOS_TABLE.' as ui
+ on u.'.$conf['user_fields']['id'].' = ui.user_id
+ where
+ u.'.$conf['user_fields']['id'].' in ('.implode(',', array_keys($c13y_users)).')
+ ;';
+
+
+ $status = array();
+
+ $result = pwg_query($query);
+ while ($row = pwg_db_fetch_assoc($result))
+ {
+ $status[$row['id']] = $row['status'];
+ }
+
+ foreach ($c13y_users as $id => $data)
+ {
+ if (!array_key_exists($id, $status))
+ {
+ $c13y->add_anomaly(l10n($data['l10n_non_existent']), 'c13y_correction_user',
+ array('id' => $id, 'action' => 'creation'));
+ }
+ else
+ if (!empty($data['status']) and $status[$id] != $data['status'])
+ {
+ $c13y->add_anomaly(l10n($data['l10n_bad_status']), 'c13y_correction_user',
+ array('id' => $id, 'action' => 'status'));
+ }
+ }
+ }
+
+ /**
+ * Do correction user
+ *
+ * @param user_id, action
+ * @return boolean true if ok else false
+ */
+ function c13y_correction_user($id, $action)
+ {
+ global $conf, $page;
+
+ $result = false;
+
+ if (!empty($id))
+ {
+ switch ($action)
+ {
+ case 'creation':
+ if ($id == $conf['guest_id'])
+ {
+ $name = 'guest';
+ $password = null;
+ }
+ else if ($id == $conf['default_user_id'])
+ {
+ $name = 'guest';
+ $password = null;
+ }
+ else if ($id == $conf['webmaster_id'])
+ {
+ $name = 'webmaster';
+ $password = generate_key(6);
+ }
+
+ if (isset($name))
+ {
+ $name_ok = false;
+ while (!$name_ok)
+ {
+ $name_ok = (get_userid($name) === false);
+ if (!$name_ok)
+ {
+ $name .= generate_key(1);
+ }
+ }
+
+ $inserts = array(
+ array(
+ 'id' => $id,
+ 'username' => addslashes($name),
+ 'password' => $password
+ ),
+ );
+ mass_inserts(USERS_TABLE, array_keys($inserts[0]), $inserts);
+
+ create_user_infos($id);
+
+ $page['infos'][] = sprintf(l10n('User "%s" created with "%s" like password'), $name, $password);
+
+ $result = true;
+ }
+ break;
+ case 'status':
+ if ($id == $conf['guest_id'])
+ {
+ $status = 'guest';
+ }
+ else if ($id == $conf['default_user_id'])
+ {
+ $status = 'guest';
+ }
+ else if ($id == $conf['webmaster_id'])
+ {
+ $status = 'webmaster';
+ }
+
+ if (isset($status))
+ {
+ $updates = array(
+ array(
+ 'user_id' => $id,
+ 'status' => $status
+ ),
+ );
+ mass_updates(USER_INFOS_TABLE,
+ array('primary' => array('user_id'),'update' => array('status')),
+ $updates);
+
+ $page['infos'][] = sprintf(l10n('Status of user "%s" updated'), get_username($id));
+
+ $result = true;
+ }
+ break;
+ }
+ }
+
+ return $result;
+ }
+}
+
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/include/check_integrity.class.php b/Piwingo/piwigo-data/piwigo/admin/include/check_integrity.class.php
new file mode 100644
index 0000000..3f95dc2
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/include/check_integrity.class.php
@@ -0,0 +1,331 @@
+ignore_list = array();
+ $this->retrieve_list = array();
+ $this->build_ignore_list = array();
+ }
+
+ /**
+ * Check integrities
+ *
+ * @param void
+ * @return void
+ */
+ function check()
+ {
+ global $page, $header_notes, $conf;
+
+ // Ignore list
+ $conf_c13y_ignore = unserialize($conf['c13y_ignore']);
+ if (
+ is_array($conf_c13y_ignore) and
+ isset($conf_c13y_ignore['version']) and
+ ($conf_c13y_ignore['version'] == PHPWG_VERSION) and
+ is_array($conf_c13y_ignore['list'])
+ )
+ {
+ $ignore_list_changed = false;
+ $this->ignore_list = $conf_c13y_ignore['list'];
+ }
+ else
+ {
+ $ignore_list_changed = true;
+ $this->ignore_list = array();
+ }
+
+ // Retrieve list
+ $this->retrieve_list = array();
+ $this->build_ignore_list = array();
+
+ trigger_notify('list_check_integrity', $this);
+
+ // Information
+ if (count($this->retrieve_list) > 0)
+ {
+ $header_notes[] = l10n_dec(
+ '%d anomaly has been detected.', '%d anomalies have been detected.',
+ count($this->retrieve_list)
+ );
+ }
+
+ // Treatments
+ if (isset($_POST['c13y_submit_correction']) and isset($_POST['c13y_selection']))
+ {
+ $corrected_count = 0;
+ $not_corrected_count = 0;
+
+ foreach ($this->retrieve_list as $i => $c13y)
+ {
+ if (!empty($c13y['correction_fct']) and
+ $c13y['is_callable'] and
+ in_array($c13y['id'], $_POST['c13y_selection']))
+ {
+ if (is_array($c13y['correction_fct_args']))
+ {
+ $args = $c13y['correction_fct_args'];
+ }
+ else
+ if (!is_null($c13y['correction_fct_args']))
+ {
+ $args = array($c13y['correction_fct_args']);
+ }
+ else
+ {
+ $args = array();
+ }
+ $this->retrieve_list[$i]['corrected'] = call_user_func_array($c13y['correction_fct'], $args);
+
+ if ($this->retrieve_list[$i]['corrected'])
+ {
+ $corrected_count += 1;
+ }
+ else
+ {
+ $not_corrected_count += 1;
+ }
+ }
+ }
+
+ if ($corrected_count > 0)
+ {
+ $page['infos'][] = l10n_dec(
+ '%d anomaly has been corrected.', '%d anomalies have been detected corrected.',
+ $corrected_count
+ );
+ }
+ if ($not_corrected_count > 0)
+ {
+ $page['errors'][] = l10n_dec(
+ '%d anomaly has not been corrected.', '%d anomalies have not been corrected.',
+ $not_corrected_count
+ );
+ }
+ }
+ else
+ {
+ if (isset($_POST['c13y_submit_ignore']) and isset($_POST['c13y_selection']))
+ {
+ $ignored_count = 0;
+
+ foreach ($this->retrieve_list as $i => $c13y)
+ {
+ if (in_array($c13y['id'], $_POST['c13y_selection']))
+ {
+ $this->build_ignore_list[] = $c13y['id'];
+ $this->retrieve_list[$i]['ignored'] = true;
+ $ignored_count += 1;
+ }
+ }
+
+ if ($ignored_count > 0)
+ {
+ $page['infos'][] = l10n_dec(
+ '%d anomaly has been ignored.', '%d anomalies have been ignored.',
+ $ignored_count
+ );
+ }
+ }
+ }
+
+ $ignore_list_changed =
+ (
+ ($ignore_list_changed) or
+ (count(array_diff($this->ignore_list, $this->build_ignore_list)) > 0) or
+ (count(array_diff($this->build_ignore_list, $this->ignore_list)) > 0)
+ );
+
+ if ($ignore_list_changed)
+ {
+ $this->update_conf($this->build_ignore_list);
+ }
+ }
+
+ /**
+ * Display anomalies list
+ *
+ * @param void
+ * @return void
+ */
+ function display()
+ {
+ global $template;
+
+ $check_automatic_correction = false;
+ $submit_automatic_correction = false;
+ $submit_ignore = false;
+
+ if (isset($this->retrieve_list) and count($this->retrieve_list) > 0)
+ {
+ $template->set_filenames(array('check_integrity' => 'check_integrity.tpl'));
+
+ foreach ($this->retrieve_list as $i => $c13y)
+ {
+ $can_select = false;
+ $c13y_display = array(
+ 'id' => $c13y['id'],
+ 'anomaly' => $c13y['anomaly'],
+ 'show_ignore_msg' => false,
+ 'show_correction_success_fct' => false,
+ 'correction_error_fct' => '',
+ 'show_correction_fct' => false,
+ 'correction_error_fct' => '',
+ 'show_correction_bad_fct' => false,
+ 'correction_msg' => ''
+ );
+
+ if (isset($c13y['ignored']))
+ {
+ if ($c13y['ignored'])
+ {
+ $c13y_display['show_ignore_msg'] = true;
+ }
+ else
+ {
+ die('$c13y[\'ignored\'] cannot be false');
+ }
+ }
+ else
+ {
+ if (!empty($c13y['correction_fct']))
+ {
+ if (isset($c13y['corrected']))
+ {
+ if ($c13y['corrected'])
+ {
+ $c13y_display['show_correction_success_fct'] = true;
+ }
+ else
+ {
+ $c13y_display['correction_error_fct'] = $this->get_htlm_links_more_info();
+ }
+ }
+ else if ($c13y['is_callable'])
+ {
+ $c13y_display['show_correction_fct'] = true;
+ $template->append('c13y_do_check', $c13y['id']);
+ $submit_automatic_correction = true;
+ $can_select = true;
+ }
+ else
+ {
+ $c13y_display['show_correction_bad_fct'] = true;
+ $can_select = true;
+ }
+ }
+ else
+ {
+ $can_select = true;
+ }
+
+ if (!empty($c13y['correction_msg']) and !isset($c13y['corrected']))
+ {
+ $c13y_display['correction_msg'] = $c13y['correction_msg'];
+ }
+ }
+
+ $c13y_display['can_select'] = $can_select;
+ if ($can_select)
+ {
+ $submit_ignore = true;
+ }
+
+ $template->append('c13y_list', $c13y_display);
+ }
+
+ $template->assign('c13y_show_submit_automatic_correction', $submit_automatic_correction);
+ $template->assign('c13y_show_submit_ignore', $submit_ignore);
+
+ $template->concat('ADMIN_CONTENT', $template->parse('check_integrity', true));
+
+ }
+ }
+
+ /**
+ * Add anomaly data
+ *
+ * @param anomaly arguments
+ * @return void
+ */
+ function add_anomaly($anomaly, $correction_fct = null, $correction_fct_args = null, $correction_msg = null)
+ {
+ $id = md5($anomaly.$correction_fct.serialize($correction_fct_args).$correction_msg);
+
+ if (in_array($id, $this->ignore_list))
+ {
+ $this->build_ignore_list[] = $id;
+ }
+ else
+ {
+ $this->retrieve_list[] =
+ array(
+ 'id' => $id,
+ 'anomaly' => $anomaly,
+ 'correction_fct' => $correction_fct,
+ 'correction_fct_args' => $correction_fct_args,
+ 'correction_msg' => $correction_msg,
+ 'is_callable' => is_callable($correction_fct));
+ }
+ }
+
+ /**
+ * Update table config
+ *
+ * @param ignore list array
+ * @return void
+ */
+ function update_conf($conf_ignore_list = array())
+ {
+ $conf_c13y_ignore = array();
+ $conf_c13y_ignore['version'] = PHPWG_VERSION;
+ $conf_c13y_ignore['list'] = $conf_ignore_list;
+ $query = 'update '.CONFIG_TABLE.' set value =\''.serialize($conf_c13y_ignore).'\'where param = \'c13y_ignore\';';
+ pwg_query($query);
+ }
+
+ /**
+ * Apply maintenance
+ *
+ * @param void
+ * @return void
+ */
+ function maintenance()
+ {
+ $this->update_conf();
+ }
+
+ /**
+ * Returns links more informations
+ *
+ * @param void
+ * @return html links
+ */
+ function get_htlm_links_more_info()
+ {
+ $pwg_links = pwg_URL();
+ $link_fmt = '%s';
+ return
+ sprintf
+ (
+ l10n('Go to %s or %s for more informations'),
+ sprintf($link_fmt, $pwg_links['FORUM'], l10n('the forum')),
+ sprintf($link_fmt, $pwg_links['WIKI'], l10n('the wiki'))
+ );
+ }
+
+}
+
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/include/configuration_sizes_process.inc.php b/Piwingo/piwigo-data/piwigo/admin/include/configuration_sizes_process.inc.php
new file mode 100644
index 0000000..9110c83
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/include/configuration_sizes_process.inc.php
@@ -0,0 +1,267 @@
+ 98)
+{
+ $errors['resize_quality'] = '[50..98]';
+}
+
+$pderivatives = $_POST['d'];
+
+// step 1 - sanitize HTML input
+foreach ($pderivatives as $type => &$pderivative)
+{
+ if ($pderivative['must_square'] = ($type==IMG_SQUARE ? true : false))
+ {
+ $pderivative['h'] = $pderivative['w'];
+ $pderivative['minh'] = $pderivative['minw'] = $pderivative['w'];
+ $pderivative['crop'] = 100;
+ }
+ $pderivative['must_enable'] = ($type==IMG_SQUARE || $type==IMG_THUMB || $type==$conf['derivative_default_size'])? true : false;
+ $pderivative['enabled'] = isset($pderivative['enabled']) || $pderivative['must_enable'] ? true : false;
+
+ if (isset($pderivative['crop']))
+ {
+ $pderivative['crop'] = 100;
+ $pderivative['minw'] = $pderivative['w'];
+ $pderivative['minh'] = $pderivative['h'];
+ }
+ else
+ {
+ $pderivative['crop'] = 0;
+ $pderivative['minw'] = null;
+ $pderivative['minh'] = null;
+ }
+}
+unset($pderivative);
+
+// step 2 - check validity
+$prev_w = $prev_h = 0;
+foreach(ImageStdParams::get_all_types() as $type)
+{
+ $pderivative = $pderivatives[$type];
+ if (!$pderivative['enabled'])
+ {
+ continue;
+ }
+
+ if ($type == IMG_THUMB)
+ {
+ $w = intval($pderivative['w']);
+ if ($w <= 0)
+ {
+ $errors[$type]['w'] = '>0';
+ }
+
+ $h = intval($pderivative['h']);
+ if ($h <= 0)
+ {
+ $errors[$type]['h'] = '>0';
+ }
+
+ if (max($w,$h) <= $prev_w)
+ {
+ $errors[$type]['w'] = $errors[$type]['h'] = '>'.$prev_w;
+ }
+ }
+ else
+ {
+ $v = intval($pderivative['w']);
+ if ($v <= 0 or $v <= $prev_w)
+ {
+ $errors[$type]['w'] = '>'.$prev_w;
+ }
+
+ $v = intval($pderivative['h']);
+ if ($v <= 0 or $v <= $prev_h)
+ {
+ $errors[$type]['h'] = '>'.$prev_h;
+ }
+ }
+
+ if (count($errors) == 0)
+ {
+ $prev_w = intval($pderivative['w']);
+ $prev_h = intval($pderivative['h']);
+ }
+
+ $v = intval($pderivative['sharpen']);
+ if ($v<0 || $v>100)
+ {
+ $errors[$type]['sharpen'] = '[0..100]';
+ }
+}
+
+// step 3 - save data
+if (count($errors) == 0)
+{
+ $quality_changed = ImageStdParams::$quality != intval($_POST['resize_quality']);
+ ImageStdParams::$quality = intval($_POST['resize_quality']);
+
+ $enabled = ImageStdParams::get_defined_type_map();
+ $disabled = safe_unserialize(ImageStdParams::get_disabled_type_map());
+ if ($disabled === false)
+ {
+ $disabled = array();
+ }
+ $changed_types = array();
+
+ foreach (ImageStdParams::get_all_types() as $type)
+ {
+ $pderivative = $pderivatives[$type];
+
+ if ($pderivative['enabled'])
+ {
+ $new_params = new DerivativeParams(
+ new SizingParams(
+ array(intval($pderivative['w']), intval($pderivative['h'])),
+ round($pderivative['crop'] / 100, 2),
+ array(intval($pderivative['minw']), intval($pderivative['minh']))
+ )
+ );
+ $new_params->sharpen = intval($pderivative['sharpen']);
+
+ ImageStdParams::apply_global($new_params);
+
+ if (isset($enabled[$type]))
+ {
+ $old_params = $enabled[$type];
+ $same = true;
+ if (!size_equals($old_params->sizing->ideal_size, $new_params->sizing->ideal_size)
+ or $old_params->sizing->max_crop != $new_params->sizing->max_crop)
+ {
+ $same = false;
+ }
+
+ if ($same
+ and $new_params->sizing->max_crop != 0
+ and !size_equals($old_params->sizing->min_size, $new_params->sizing->min_size))
+ {
+ $same = false;
+ }
+
+ if ($quality_changed
+ || $new_params->sharpen != $old_params->sharpen)
+ {
+ $same = false;
+ }
+
+ if (!$same)
+ {
+ $new_params->last_mod_time = time();
+ $changed_types[] = $type;
+ }
+ else
+ {
+ $new_params->last_mod_time = $old_params->last_mod_time;
+ }
+ $enabled[$type] = $new_params;
+ }
+ else
+ {// now enabled, before was disabled
+ $enabled[$type] = $new_params;
+ unset($disabled[$type]);
+ }
+ }
+ else
+ {// disabled
+ if (isset($enabled[$type]))
+ {// now disabled, before was enabled
+ $changed_types[] = $type;
+ $disabled[$type] = $enabled[$type];
+ unset($enabled[$type]);
+ }
+ }
+ }
+
+ $enabled_by = array(); // keys ordered by all types
+ foreach(ImageStdParams::get_all_types() as $type)
+ {
+ if (isset($enabled[$type]))
+ {
+ $enabled_by[$type] = $enabled[$type];
+ }
+ }
+
+ foreach( array_keys(ImageStdParams::$custom) as $custom)
+ {
+ if (isset($_POST['delete_custom_derivative_'.$custom]))
+ {
+ $changed_types[] = $custom;
+ unset(ImageStdParams::$custom[$custom]);
+ }
+ }
+
+ ImageStdParams::set_and_save($enabled_by);
+ ImageStdParams::set_and_save_disabled($disabled);
+
+ if (count($changed_types))
+ {
+ clear_derivative_cache($changed_types);
+ }
+
+ $template->assign(
+ array(
+ 'save_success' => l10n('Your configuration settings are saved'),
+ )
+ );
+
+ pwg_activity('system', ACTIVITY_SYSTEM_CORE, 'config', array('config_section'=>'sizes'));
+}
+else
+{
+ foreach ($original_fields as $field)
+ {
+ if (isset($_POST[$field]))
+ {
+ $template->append(
+ 'sizes',
+ array(
+ $field => strip_tags($_POST[$field]) // strip_tags prevents from XSS attempt
+ ),
+ true
+ );
+ }
+ }
+
+ $template->assign('derivatives', $pderivatives);
+ $template->assign('ferrors', $errors);
+ $template->assign('resize_quality', $_POST['resize_quality']);
+ $page['sizes_loaded_in_tpl'] = true;
+}
+?>
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/include/configuration_watermark_process.inc.php b/Piwingo/piwigo-data/piwigo/admin/include/configuration_watermark_process.inc.php
new file mode 100644
index 0000000..b9d976d
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/include/configuration_watermark_process.inc.php
@@ -0,0 +1,211 @@
+ 100)
+{
+ $errors['watermark']['xpos'] = '[0..100]';
+}
+
+$v = intval($pwatermark['ypos']);
+if ($v < 0 or $v > 100)
+{
+ $errors['watermark']['ypos'] = '[0..100]';
+}
+
+$v = intval($pwatermark['opacity']);
+if ($v <= 0 or $v > 100)
+{
+ $errors['watermark']['opacity'] = '(0..100]';
+}
+
+// step 3 - save data
+if (count($errors) == 0)
+{
+ $watermark = new WatermarkParams();
+ $watermark->file = $pwatermark['file'];
+ $watermark->xpos = intval($pwatermark['xpos']);
+ $watermark->ypos = intval($pwatermark['ypos']);
+ $watermark->xrepeat = intval($pwatermark['xrepeat']);
+ $watermark->yrepeat = intval($pwatermark['yrepeat']);
+ $watermark->opacity = intval($pwatermark['opacity']);
+ $watermark->min_size = array(intval($pwatermark['minw']),intval($pwatermark['minh']));
+
+ $old_watermark = ImageStdParams::get_watermark();
+ $watermark_changed =
+ $watermark->file != $old_watermark->file
+ || $watermark->xpos != $old_watermark->xpos
+ || $watermark->ypos != $old_watermark->ypos
+ || $watermark->xrepeat != $old_watermark->xrepeat
+ || $watermark->yrepeat != $old_watermark->yrepeat
+ || $watermark->opacity != $old_watermark->opacity;
+
+ // save the new watermark configuration
+ ImageStdParams::set_watermark($watermark);
+
+ // do we have to regenerate the derivatives (and which types)?
+ $changed_types = array();
+
+ foreach (ImageStdParams::get_defined_type_map() as $type => $params)
+ {
+ $old_use_watermark = $params->use_watermark;
+ ImageStdParams::apply_global($params);
+
+ $changed = $params->use_watermark != $old_use_watermark;
+ if (!$changed and $params->use_watermark)
+ {
+ $changed = $watermark_changed;
+ }
+ if (!$changed and $params->use_watermark)
+ {
+ // if thresholds change and before/after the threshold is lower than the corresponding derivative side -> some derivatives might switch the watermark
+ $changed |= $watermark->min_size[0]!=$old_watermark->min_size[0] and ($watermark->min_size[0]<$params->max_width() or $old_watermark->min_size[0]<$params->max_width());
+ $changed |= $watermark->min_size[1]!=$old_watermark->min_size[1] and ($watermark->min_size[1]<$params->max_height() or $old_watermark->min_size[1]<$params->max_height());
+ }
+
+ if ($changed)
+ {
+ $params->last_mod_time = time();
+ $changed_types[] = $type;
+ }
+ }
+
+ ImageStdParams::save();
+
+ if (count($changed_types))
+ {
+ clear_derivative_cache($changed_types);
+ }
+
+ $template->assign(
+ array(
+ 'save_success' => l10n('Your configuration settings are saved'),
+ )
+ );
+
+ pwg_activity('system', ACTIVITY_SYSTEM_CORE, 'config', array('config_section'=>'watermark'));
+}
+else
+{
+ $template->assign('watermark', $pwatermark);
+ $template->assign('ferrors', $errors);
+}
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/include/functions.php b/Piwingo/piwigo-data/piwigo/admin/include/functions.php
new file mode 100644
index 0000000..c5a26eb
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/include/functions.php
@@ -0,0 +1,3903 @@
+ 0)
+ {
+ if ('delete_orphans' == $photo_deletion_mode)
+ {
+ $query = '
+SELECT
+ DISTINCT(image_id)
+ FROM '.IMAGE_CATEGORY_TABLE.'
+ WHERE image_id IN ('.implode(',', $image_ids_linked).')
+ AND category_id NOT IN ('.implode(',', $ids).')
+;';
+ $image_ids_not_orphans = query2array($query, null, 'image_id');
+ $image_ids_to_delete = array_diff($image_ids_linked, $image_ids_not_orphans);
+ }
+
+ if ('force_delete' == $photo_deletion_mode)
+ {
+ $image_ids_to_delete = $image_ids_linked;
+ }
+
+ delete_elements($image_ids_to_delete, true);
+ }
+ }
+
+ // destruction of the links between images and this category
+ $query = '
+DELETE FROM '.IMAGE_CATEGORY_TABLE.'
+ WHERE category_id IN (
+'.wordwrap(implode(', ', $ids), 80, "\n").')
+;';
+ pwg_query($query);
+
+ // destruction of the access linked to the category
+ $query = '
+DELETE FROM '.USER_ACCESS_TABLE.'
+ WHERE cat_id IN (
+'.wordwrap(implode(', ', $ids), 80, "\n").')
+;';
+ pwg_query($query);
+
+ $query = '
+DELETE FROM '.GROUP_ACCESS_TABLE.'
+ WHERE cat_id IN (
+'.wordwrap(implode(', ', $ids), 80, "\n").')
+;';
+ pwg_query($query);
+
+ // destruction of the category
+ $query = '
+DELETE FROM '.CATEGORIES_TABLE.'
+ WHERE id IN (
+'.wordwrap(implode(', ', $ids), 80, "\n").')
+;';
+ pwg_query($query);
+
+ $query='
+DELETE FROM '.OLD_PERMALINKS_TABLE.'
+ WHERE cat_id IN ('.implode(',',$ids).')';
+ pwg_query($query);
+
+ $query='
+DELETE FROM '.USER_CACHE_CATEGORIES_TABLE.'
+ WHERE cat_id IN ('.implode(',',$ids).')';
+ pwg_query($query);
+
+ trigger_notify('delete_categories', $ids);
+ pwg_activity('album', $ids, 'delete', array('photo_deletion_mode'=>$photo_deletion_mode));
+}
+
+/**
+ * Deletes all files (on disk) related to given image ids.
+ *
+ * @param int[] $ids
+ * @return 0|int[] image ids where files were successfully deleted
+ */
+function delete_element_files($ids)
+{
+ global $conf;
+ if (count($ids) == 0)
+ {
+ return 0;
+ }
+
+ $new_ids = array();
+ $formats_of = array();
+
+ $query = '
+SELECT
+ image_id,
+ ext
+ FROM '.IMAGE_FORMAT_TABLE.'
+ WHERE image_id IN ('.implode(',', $ids).')
+;';
+ $result = pwg_query($query);
+ while ($row = pwg_db_fetch_assoc($result))
+ {
+ if (!isset($formats_of[ $row['image_id'] ]))
+ {
+ $formats_of[ $row['image_id'] ] = array();
+ }
+
+ $formats_of[ $row['image_id'] ][] = $row['ext'];
+ }
+
+ $query = '
+SELECT
+ id,
+ path,
+ representative_ext
+ FROM '.IMAGES_TABLE.'
+ WHERE id IN ('.implode(',', $ids).')
+;';
+ $result = pwg_query($query);
+ while ($row = pwg_db_fetch_assoc($result))
+ {
+ if (url_is_remote($row['path']))
+ {
+ continue;
+ }
+
+ $files = array();
+ $files[] = get_element_path($row);
+
+ if (!empty($row['representative_ext']))
+ {
+ $files[] = original_to_representative( $files[0], $row['representative_ext']);
+ }
+
+ if (isset($formats_of[ $row['id'] ]))
+ {
+ foreach ($formats_of[ $row['id'] ] as $format_ext)
+ {
+ $files[] = original_to_format($files[0], $format_ext);
+ }
+ }
+
+ $ok = true;
+ if (!isset($conf['never_delete_originals']))
+ {
+ foreach ($files as $path)
+ {
+ if (is_file($path) and !unlink($path))
+ {
+ $ok = false;
+ trigger_error('"'.$path.'" cannot be removed', E_USER_WARNING);
+ break;
+ }
+ }
+ }
+
+ if ($ok)
+ {
+ delete_element_derivatives($row);
+ $new_ids[] = $row['id'];
+ }
+ else
+ {
+ break;
+ }
+ }
+ return $new_ids;
+}
+
+/**
+ * Deletes elements from database.
+ * It also deletes :
+ * - all the comments related to elements
+ * - all the links between categories/tags and elements
+ * - all the favorites/rates associated to elements
+ * - removes elements from caddie
+ *
+ * @param int[] $ids
+ * @param bool $physical_deletion
+ * @return int number of deleted elements
+ */
+function delete_elements($ids, $physical_deletion=false)
+{
+ if (count($ids) == 0)
+ {
+ return 0;
+ }
+ trigger_notify('begin_delete_elements', $ids);
+
+ if ($physical_deletion)
+ {
+ $ids = delete_element_files($ids);
+ if (count($ids)==0)
+ {
+ return 0;
+ }
+ }
+
+ $ids_str = wordwrap(implode(', ', $ids), 80, "\n");
+
+ // destruction of the comments on the image
+ $query = '
+DELETE FROM '.COMMENTS_TABLE.'
+ WHERE image_id IN ('. $ids_str .')
+;';
+ pwg_query($query);
+
+ // destruction of the links between images and categories
+ $query = '
+DELETE FROM '.IMAGE_CATEGORY_TABLE.'
+ WHERE image_id IN ('. $ids_str .')
+;';
+ pwg_query($query);
+
+ // destruction of the formats
+ $query = '
+DELETE FROM '.IMAGE_FORMAT_TABLE.'
+ WHERE image_id IN ('. $ids_str .')
+;';
+ pwg_query($query);
+
+ // destruction of the links between images and tags
+ $query = '
+DELETE FROM '.IMAGE_TAG_TABLE.'
+ WHERE image_id IN ('. $ids_str .')
+;';
+ pwg_query($query);
+
+ // destruction of the favorites associated with the picture
+ $query = '
+DELETE FROM '.FAVORITES_TABLE.'
+ WHERE image_id IN ('. $ids_str .')
+;';
+ pwg_query($query);
+
+ // destruction of the rates associated to this element
+ $query = '
+DELETE FROM '.RATE_TABLE.'
+ WHERE element_id IN ('. $ids_str .')
+;';
+ pwg_query($query);
+
+ // destruction of the caddie associated to this element
+ $query = '
+DELETE FROM '.CADDIE_TABLE.'
+ WHERE element_id IN ('. $ids_str .')
+;';
+ pwg_query($query);
+
+ // destruction of the image
+ $query = '
+DELETE FROM '.IMAGES_TABLE.'
+ WHERE id IN ('. $ids_str .')
+;';
+ pwg_query($query);
+
+ // are the photo used as category representant?
+ $query = '
+SELECT
+ id
+ FROM '.CATEGORIES_TABLE.'
+ WHERE representative_picture_id IN ('. $ids_str .')
+;';
+ $category_ids = query2array($query, null, 'id');
+ if (count($category_ids) > 0)
+ {
+ update_category($category_ids);
+ }
+
+ trigger_notify('delete_elements', $ids);
+ pwg_activity('photo', $ids, 'delete');
+ return count($ids);
+}
+
+/**
+ * Deletes an user.
+ * It also deletes all related data (accesses, favorites, permissions, etc.)
+ * @todo : accept array input
+ *
+ * @param int $user_id
+ */
+function delete_user($user_id)
+{
+ global $conf;
+ $tables = array(
+ // destruction of the access linked to the user
+ USER_ACCESS_TABLE,
+ // destruction of data notification by mail for this user
+ USER_MAIL_NOTIFICATION_TABLE,
+ // destruction of data RSS notification for this user
+ USER_FEED_TABLE,
+ // deletion of calculated permissions linked to the user
+ USER_CACHE_TABLE,
+ // deletion of computed cache data linked to the user
+ USER_CACHE_CATEGORIES_TABLE,
+ // destruction of the group links for this user
+ USER_GROUP_TABLE,
+ // destruction of the favorites associated with the user
+ FAVORITES_TABLE,
+ // destruction of the caddie associated with the user
+ CADDIE_TABLE,
+ // deletion of piwigo specific informations
+ USER_INFOS_TABLE,
+ USER_AUTH_KEYS_TABLE
+ );
+
+ foreach ($tables as $table)
+ {
+ $query = '
+DELETE FROM '.$table.'
+ WHERE user_id = '.$user_id.'
+;';
+ pwg_query($query);
+ }
+
+ // purge of sessions
+ delete_user_sessions($user_id);
+
+ // destruction of the user
+ $query = '
+DELETE FROM '.USERS_TABLE.'
+ WHERE '.$conf['user_fields']['id'].' = '.$user_id.'
+;';
+ pwg_query($query);
+
+ trigger_notify('delete_user', $user_id);
+ pwg_activity('user', $user_id, 'delete');
+}
+
+/**
+ * Deletes all tags linked to no photo
+ */
+function delete_orphan_tags()
+{
+ $orphan_tags = get_orphan_tags();
+
+ if (count($orphan_tags) > 0)
+ {
+ $orphan_tag_ids = array();
+ foreach ($orphan_tags as $tag)
+ {
+ $orphan_tag_ids[] = $tag['id'];
+ }
+
+ delete_tags($orphan_tag_ids);
+ }
+}
+
+/**
+ * Get all tags (id + name) linked to no photo
+ */
+function get_orphan_tags()
+{
+ $query = '
+SELECT
+ id,
+ name
+ FROM '.TAGS_TABLE.'
+ LEFT JOIN '.IMAGE_TAG_TABLE.' ON id = tag_id
+ WHERE tag_id IS NULL
+ AND lastmodified < SUBDATE(NOW(), INTERVAL 1 DAY)
+;';
+ return query2array($query);
+}
+
+/**
+ * Verifies that the representative picture really exists in the db and
+ * picks up a random representative if possible and based on config.
+ *
+ * @param 'all'|int|int[] $ids
+ */
+function update_category($ids = 'all')
+{
+ global $conf;
+
+ if ($ids=='all')
+ {
+ $where_cats = '1=1';
+ }
+ elseif ( !is_array($ids) )
+ {
+ $where_cats = '%s='.$ids;
+ }
+ else
+ {
+ if (count($ids) == 0)
+ {
+ return false;
+ }
+ $where_cats = '%s IN('.wordwrap(implode(', ', $ids), 120, "\n").')';
+ }
+
+ // find all categories where the setted representative is not possible :
+ // the picture does not exist
+ $query = '
+SELECT DISTINCT c.id
+ FROM '.CATEGORIES_TABLE.' AS c LEFT JOIN '.IMAGES_TABLE.' AS i
+ ON c.representative_picture_id = i.id
+ WHERE representative_picture_id IS NOT NULL
+ AND '.sprintf($where_cats, 'c.id').'
+ AND i.id IS NULL
+;';
+ $wrong_representant = query2array($query, null, 'id');
+
+ if (count($wrong_representant) > 0)
+ {
+ $query = '
+UPDATE '.CATEGORIES_TABLE.'
+ SET representative_picture_id = NULL
+ WHERE id IN ('.wordwrap(implode(', ', $wrong_representant), 120, "\n").')
+;';
+ pwg_query($query);
+ }
+
+ if (!$conf['allow_random_representative'])
+ {
+ // If the random representant is not allowed, we need to find
+ // categories with elements and with no representant. Those categories
+ // must be added to the list of categories to set to a random
+ // representant.
+ $query = '
+SELECT DISTINCT id
+ FROM '.CATEGORIES_TABLE.' INNER JOIN '.IMAGE_CATEGORY_TABLE.'
+ ON id = category_id
+ WHERE representative_picture_id IS NULL
+ AND '.sprintf($where_cats, 'category_id').'
+;';
+ $to_rand = query2array($query, null, 'id');
+ if (count($to_rand) > 0)
+ {
+ set_random_representant($to_rand);
+ }
+ }
+}
+
+/**
+ * Checks and repairs IMAGE_CATEGORY_TABLE integrity.
+ * Removes all entries from the table which correspond to a deleted image.
+ */
+function images_integrity()
+{
+ $query = '
+SELECT
+ image_id
+ FROM '.IMAGE_CATEGORY_TABLE.'
+ LEFT JOIN '.IMAGES_TABLE.' ON id = image_id
+ WHERE id IS NULL
+;';
+ $orphan_image_ids = query2array($query, null, 'image_id');
+
+ if (count($orphan_image_ids) > 0)
+ {
+ $query = '
+DELETE
+ FROM '.IMAGE_CATEGORY_TABLE.'
+ WHERE image_id IN ('.implode(',', $orphan_image_ids).')
+;';
+ pwg_query($query);
+ }
+}
+
+/**
+ * Checks and repairs integrity on categories.
+ * Removes all entries from related tables which correspond to a deleted category.
+ */
+function categories_integrity()
+{
+ $related_columns = array(
+ IMAGE_CATEGORY_TABLE.'.category_id',
+ USER_ACCESS_TABLE.'.cat_id',
+ GROUP_ACCESS_TABLE.'.cat_id',
+ OLD_PERMALINKS_TABLE.'.cat_id',
+ USER_CACHE_CATEGORIES_TABLE.'.cat_id',
+ );
+
+ foreach ($related_columns as $fullcol)
+ {
+ list($table, $column) = explode('.', $fullcol);
+
+ $query = '
+SELECT
+ '.$column.'
+ FROM '.$table.'
+ LEFT JOIN '.CATEGORIES_TABLE.' ON id = '.$column.'
+ WHERE id IS NULL
+;';
+ $orphans = array_unique(query2array($query, null, $column));
+
+ if (count($orphans) > 0)
+ {
+ $query = '
+DELETE
+ FROM '.$table.'
+ WHERE '.$column.' IN ('.implode(',', $orphans).')
+;';
+ pwg_query($query);
+ }
+ }
+}
+
+/**
+ * Returns an array containing sub-directories which are potentially
+ * a category.
+ * Directories named ".svn", "thumbnail", "pwg_high" or "pwg_representative"
+ * are omitted.
+ *
+ * @param string $basedir (eg: ./galleries)
+ * @return string[]
+ */
+function get_fs_directories($path, $recursive = true)
+{
+ global $conf;
+
+ $dirs = array();
+ $path = rtrim($path, '/');
+
+ $exclude_folders = array_merge(
+ $conf['sync_exclude_folders'],
+ array(
+ '.', '..', '.svn',
+ 'thumbnail', 'pwg_high',
+ 'pwg_representative',
+ 'pwg_format',
+ )
+ );
+ $exclude_folders = array_flip($exclude_folders);
+
+ if (is_dir($path))
+ {
+ if ($contents = opendir($path))
+ {
+ while (($node = readdir($contents)) !== false)
+ {
+ if (is_dir($path.'/'.$node) and !isset($exclude_folders[$node]))
+ {
+ $dirs[] = $path.'/'.$node;
+ if ($recursive)
+ {
+ $dirs = array_merge($dirs, get_fs_directories($path.'/'.$node));
+ }
+ }
+ }
+ closedir($contents);
+ }
+ }
+
+ return $dirs;
+}
+
+/**
+ * save the rank depending on given categories order
+ *
+ * The list of ordered categories id is supposed to be in the same parent
+ * category
+ *
+ * @param array categories
+ * @return void
+ */
+function save_categories_order($categories)
+{
+ $current_rank_for_id_uppercat = array();
+ $current_rank = 0;
+
+ $datas = array();
+ foreach ($categories as $category)
+ {
+ if (is_array($category))
+ {
+ $id = $category['id'];
+ $id_uppercat = $category['id_uppercat'];
+
+ if (!isset($current_rank_for_id_uppercat[$id_uppercat]))
+ {
+ $current_rank_for_id_uppercat[$id_uppercat] = 0;
+ }
+ $current_rank = ++$current_rank_for_id_uppercat[$id_uppercat];
+ }
+ else
+ {
+ $id = $category;
+ $current_rank++;
+ }
+
+ $datas[] = array('id' => $id, 'rank' => $current_rank);
+ }
+ $fields = array('primary' => array('id'), 'update' => array('rank'));
+ mass_updates(CATEGORIES_TABLE, $fields, $datas);
+
+ update_global_rank();
+}
+
+/**
+ * Orders categories (update categories.rank and global_rank database fields)
+ * so that rank field are consecutive integers starting at 1 for each child.
+ */
+function update_global_rank()
+{
+ $query = '
+SELECT id, id_uppercat, uppercats, `rank`, global_rank
+ FROM '.CATEGORIES_TABLE.'
+ ORDER BY id_uppercat, `rank`, name';
+
+ global $cat_map; // used in preg_replace callback
+ $cat_map = array();
+
+ $current_rank = 0;
+ $current_uppercat = '';
+
+ $result = pwg_query($query);
+ while ($row = pwg_db_fetch_assoc($result))
+ {
+ if ($row['id_uppercat'] != $current_uppercat)
+ {
+ $current_rank = 0;
+ $current_uppercat = $row['id_uppercat'];
+ }
+ ++$current_rank;
+ $cat =
+ array(
+ 'rank' => $current_rank,
+ 'rank_changed' =>$current_rank!=$row['rank'],
+ 'global_rank' => $row['global_rank'],
+ 'uppercats' => $row['uppercats'],
+ );
+ $cat_map[ $row['id'] ] = $cat;
+ }
+
+ $datas = array();
+
+ $cat_map_callback = function($m) use ($cat_map) { return $cat_map[$m[1]]["rank"]; };
+
+ foreach( $cat_map as $id=>$cat )
+ {
+ $new_global_rank = preg_replace_callback(
+ '/(\d+)/',
+ $cat_map_callback,
+ str_replace(',', '.', $cat['uppercats'] )
+ );
+
+ if ($cat['rank_changed'] or $new_global_rank !== $cat['global_rank'])
+ {
+ $datas[] = array(
+ 'id' => $id,
+ 'rank' => $cat['rank'],
+ 'global_rank' => $new_global_rank,
+ );
+ }
+ }
+
+ unset($cat_map);
+
+ mass_updates(
+ CATEGORIES_TABLE,
+ array(
+ 'primary' => array('id'),
+ 'update' => array('rank', 'global_rank')
+ ),
+ $datas
+ );
+ return count($datas);
+}
+
+/**
+ * Change the **visible** property on a set of categories.
+ *
+ * @param int[] $categories
+ * @param boolean|string $value
+ * @param boolean $unlock_child optional default false
+ */
+function set_cat_visible($categories, $value, $unlock_child = false)
+{
+ if ( ($value = filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)) === null )
+ {
+ trigger_error("set_cat_visible invalid param $value", E_USER_WARNING);
+ return false;
+ }
+
+ // unlocking a category => all its parent categories become unlocked
+ if ($value)
+ {
+ $cats = get_uppercat_ids($categories);
+ if ($unlock_child) {
+ $cats = array_merge($cats, get_subcat_ids($categories));
+ }
+ $query = '
+UPDATE '.CATEGORIES_TABLE.'
+ SET visible = \'true\'
+ WHERE id IN ('.implode(',', $cats).')';
+ pwg_query($query);
+ }
+ // locking a category => all its child categories become locked
+ else
+ {
+ $subcats = get_subcat_ids($categories);
+ $query = '
+UPDATE '.CATEGORIES_TABLE.'
+ SET visible = \'false\'
+ WHERE id IN ('.implode(',', $subcats).')';
+ pwg_query($query);
+ }
+}
+
+/**
+ * Change the **status** property on a set of categories : private or public.
+ *
+ * @param int[] $categories
+ * @param string $value
+ */
+function set_cat_status($categories, $value)
+{
+ if (!in_array($value, array('public', 'private')))
+ {
+ trigger_error("set_cat_status invalid param $value", E_USER_WARNING);
+ return false;
+ }
+
+ // make public a category => all its parent categories become public
+ if ($value == 'public')
+ {
+ $uppercats = get_uppercat_ids($categories);
+ $query = '
+UPDATE '.CATEGORIES_TABLE.'
+ SET status = \'public\'
+ WHERE id IN ('.implode(',', $uppercats).')
+;';
+ pwg_query($query);
+ }
+
+ // make a category private => all its child categories become private
+ if ($value == 'private')
+ {
+ $subcats = get_subcat_ids($categories);
+
+ $query = '
+UPDATE '.CATEGORIES_TABLE.'
+ SET status = \'private\'
+ WHERE id IN ('.implode(',', $subcats).')';
+ pwg_query($query);
+
+ // We have to keep permissions consistant: a sub-album can't be
+ // permitted to a user or group if its parent album is not permitted to
+ // the same user or group. Let's remove all permissions on sub-albums if
+ // it is not consistant. Let's take the following example:
+ //
+ // A1 permitted to U1,G1
+ // A1/A2 permitted to U1,U2,G1,G2
+ // A1/A2/A3 permitted to U3,G1
+ // A1/A2/A4 permitted to U2
+ // A1/A5 permitted to U4
+ // A6 permitted to U4
+ // A6/A7 permitted to G1
+ //
+ // (we consider that it can be possible to start with inconsistant
+ // permission, given that public albums can have hidden permissions,
+ // revealed once the album returns to private status)
+ //
+ // The admin selects A2,A3,A4,A5,A6,A7 to become private (all but A1,
+ // which is private, which can be true if we're moving A2 into A1). The
+ // result must be:
+ //
+ // A2 permission removed to U2,G2
+ // A3 permission removed to U3
+ // A4 permission removed to U2
+ // A5 permission removed to U2
+ // A6 permission removed to U4
+ // A7 no permission removed
+ //
+ // 1) we must extract "top albums": A2, A5 and A6
+ // 2) for each top album, decide which album is the reference for permissions
+ // 3) remove all inconsistant permissions from sub-albums of each top-album
+
+ // step 1, search top albums
+ $top_categories = array();
+ $parent_ids = array();
+
+ $query = '
+SELECT
+ id,
+ name,
+ id_uppercat,
+ uppercats,
+ global_rank
+ FROM '.CATEGORIES_TABLE.'
+ WHERE id IN ('.implode(',', $categories).')
+;';
+ $all_categories = query2array($query);
+ usort($all_categories, 'global_rank_compare');
+
+ foreach ($all_categories as $cat)
+ {
+ $is_top = true;
+
+ if (!empty($cat['id_uppercat']))
+ {
+ foreach (explode(',', $cat['uppercats']) as $id_uppercat)
+ {
+ if (isset($top_categories[$id_uppercat]))
+ {
+ $is_top = false;
+ break;
+ }
+ }
+ }
+
+ if ($is_top)
+ {
+ $top_categories[$cat['id']] = $cat;
+
+ if (!empty($cat['id_uppercat']))
+ {
+ $parent_ids[] = $cat['id_uppercat'];
+ }
+ }
+ }
+
+ // step 2, search the reference album for permissions
+ //
+ // to find the reference of each top album, we will need the parent albums
+ $parent_cats = array();
+
+ if (count($parent_ids) > 0)
+ {
+ $query = '
+SELECT
+ id,
+ status
+ FROM '.CATEGORIES_TABLE.'
+ WHERE id IN ('.implode(',', $parent_ids).')
+;';
+ $parent_cats= query2array($query, 'id');
+ }
+
+ $tables = array(
+ USER_ACCESS_TABLE => 'user_id',
+ GROUP_ACCESS_TABLE => 'group_id'
+ );
+
+ foreach ($top_categories as $top_category)
+ {
+ // what is the "reference" for list of permissions? The parent album
+ // if it is private, else the album itself
+ $ref_cat_id = $top_category['id'];
+
+ if (!empty($top_category['id_uppercat'])
+ and isset($parent_cats[ $top_category['id_uppercat'] ])
+ and 'private' == $parent_cats[ $top_category['id_uppercat'] ]['status'])
+ {
+ $ref_cat_id = $top_category['id_uppercat'];
+ }
+
+ $subcats = get_subcat_ids(array($top_category['id']));
+
+ foreach ($tables as $table => $field)
+ {
+ // what are the permissions user/group of the reference album
+ $query = '
+SELECT '.$field.'
+ FROM '.$table.'
+ WHERE cat_id = '.$ref_cat_id.'
+;';
+ $ref_access = query2array($query, null, $field);
+
+ if (count($ref_access) == 0)
+ {
+ $ref_access[] = -1;
+ }
+
+ // step 3, remove the inconsistant permissions from sub-albums
+ $query = '
+DELETE
+ FROM '.$table.'
+ WHERE '.$field.' NOT IN ('.implode(',', $ref_access).')
+ AND cat_id IN ('.implode(',', $subcats).')
+;';
+ pwg_query($query);
+ }
+ }
+ }
+}
+
+/**
+ * Returns all uppercats category ids of the given category ids.
+ *
+ * @param int[] $cat_ids
+ * @return int[]
+ */
+function get_uppercat_ids($cat_ids)
+{
+ if (!is_array($cat_ids) or count($cat_ids) < 1)
+ {
+ return array();
+ }
+
+ $uppercats = array();
+
+ $query = '
+SELECT uppercats
+ FROM '.CATEGORIES_TABLE.'
+ WHERE id IN ('.implode(',', $cat_ids).')
+;';
+ $result = pwg_query($query);
+ while ($row = pwg_db_fetch_assoc($result))
+ {
+ $uppercats = array_merge($uppercats,
+ explode(',', $row['uppercats']));
+ }
+ $uppercats = array_unique($uppercats);
+
+ return $uppercats;
+}
+
+/**
+ */
+function get_category_representant_properties($image_id, $size = NULL)
+{
+ $query = '
+SELECT id,representative_ext,path
+ FROM '.IMAGES_TABLE.'
+ WHERE id = '.$image_id.'
+;';
+
+ $row = pwg_db_fetch_assoc(pwg_query($query));
+ if ($size == NULL) {
+ $src = DerivativeImage::thumb_url($row);
+ } else {
+ $src = DerivativeImage::url($size, $row);
+ }
+ $url = get_root_url().'admin.php?page=photo-'.$image_id;
+
+ return array(
+ 'src' => $src,
+ 'url' => $url
+ );
+}
+
+/**
+ * Set a new random representant to the categories.
+ *
+ * @param int[] $categories
+ */
+function set_random_representant($categories)
+{
+ $datas = array();
+ foreach ($categories as $category_id)
+ {
+ $query = '
+SELECT image_id
+ FROM '.IMAGE_CATEGORY_TABLE.'
+ WHERE category_id = '.$category_id.'
+ ORDER BY '.DB_RANDOM_FUNCTION.'()
+ LIMIT 1
+;';
+ list($representative) = pwg_db_fetch_row(pwg_query($query));
+
+ $datas[] = array(
+ 'id' => $category_id,
+ 'representative_picture_id' => $representative,
+ );
+ }
+
+ mass_updates(
+ CATEGORIES_TABLE,
+ array(
+ 'primary' => array('id'),
+ 'update' => array('representative_picture_id')
+ ),
+ $datas
+ );
+}
+
+/**
+ * Returns the fulldir for each given category id.
+ *
+ * @param int[] intcat_ids
+ * @return string[]
+ */
+function get_fulldirs($cat_ids)
+{
+ if (count($cat_ids) == 0)
+ {
+ return array();
+ }
+
+ // caching directories of existing categories
+ global $cat_dirs; // used in preg_replace callback
+ $query = '
+SELECT id, dir
+ FROM '.CATEGORIES_TABLE.'
+ WHERE dir IS NOT NULL
+;';
+ $cat_dirs = query2array($query, 'id', 'dir');
+
+ // caching galleries_url
+ $query = '
+SELECT id, galleries_url
+ FROM '.SITES_TABLE.'
+;';
+ $galleries_url = query2array($query, 'id', 'galleries_url');
+
+ // categories : id, site_id, uppercats
+ $query = '
+SELECT id, uppercats, site_id
+ FROM '.CATEGORIES_TABLE.'
+ WHERE dir IS NOT NULL
+ AND id IN (
+'.wordwrap(implode(', ', $cat_ids), 80, "\n").')
+;';
+ $categories = query2array($query);
+
+ // filling $cat_fulldirs
+ $cat_dirs_callback = function($m) use ($cat_dirs) { return $cat_dirs[$m[1]]; };
+
+ $cat_fulldirs = array();
+ foreach ($categories as $category)
+ {
+ $uppercats = str_replace(',', '/', $category['uppercats']);
+ $cat_fulldirs[$category['id']] = $galleries_url[$category['site_id']];
+ $cat_fulldirs[$category['id']].= preg_replace_callback(
+ '/(\d+)/',
+ $cat_dirs_callback,
+ $uppercats
+ );
+ }
+
+ unset($cat_dirs);
+
+ return $cat_fulldirs;
+}
+
+/**
+ * Returns an array with all file system files according to $conf['file_ext']
+ *
+ * @deprecated 2.4
+ *
+ * @param string $path
+ * @param bool $recursive
+ * @return array
+ */
+function get_fs($path, $recursive = true)
+{
+ global $conf;
+
+ // because isset is faster than in_array...
+ if (!isset($conf['flip_picture_ext']))
+ {
+ $conf['flip_picture_ext'] = array_flip($conf['picture_ext']);
+ }
+ if (!isset($conf['flip_file_ext']))
+ {
+ $conf['flip_file_ext'] = array_flip($conf['file_ext']);
+ }
+
+ $fs['elements'] = array();
+ $fs['thumbnails'] = array();
+ $fs['representatives'] = array();
+ $subdirs = array();
+
+ if (is_dir($path))
+ {
+ if ($contents = opendir($path))
+ {
+ while (($node = readdir($contents)) !== false)
+ {
+ if ($node == '.' or $node == '..') continue;
+
+ if (is_file($path.'/'.$node))
+ {
+ $extension = get_extension($node);
+
+ if (isset($conf['flip_picture_ext'][$extension]))
+ {
+ if (basename($path) == 'thumbnail')
+ {
+ $fs['thumbnails'][] = $path.'/'.$node;
+ }
+ elseif (basename($path) == 'pwg_representative')
+ {
+ $fs['representatives'][] = $path.'/'.$node;
+ }
+ else
+ {
+ $fs['elements'][] = $path.'/'.$node;
+ }
+ }
+ elseif (isset($conf['flip_file_ext'][$extension]))
+ {
+ $fs['elements'][] = $path.'/'.$node;
+ }
+ }
+ elseif (is_dir($path.'/'.$node) and $node != 'pwg_high' and $recursive)
+ {
+ $subdirs[] = $node;
+ }
+ }
+ }
+ closedir($contents);
+
+ foreach ($subdirs as $subdir)
+ {
+ $tmp_fs = get_fs($path.'/'.$subdir);
+
+ $fs['elements'] = array_merge($fs['elements'],
+ $tmp_fs['elements']);
+
+ $fs['thumbnails'] = array_merge($fs['thumbnails'],
+ $tmp_fs['thumbnails']);
+
+ $fs['representatives'] = array_merge($fs['representatives'],
+ $tmp_fs['representatives']);
+ }
+ }
+ return $fs;
+}
+
+/**
+ * Synchronize base users list and related users list.
+ *
+ * Compares and synchronizes base users table (USERS_TABLE) with its child
+ * tables (USER_INFOS_TABLE, USER_ACCESS, USER_CACHE, USER_GROUP) : each
+ * base user must be present in child tables, users in child tables not
+ * present in base table must be deleted.
+ */
+function sync_users()
+{
+ global $conf;
+
+ $query = '
+SELECT '.$conf['user_fields']['id'].' AS id
+ FROM '.USERS_TABLE.'
+;';
+ $base_users = query2array($query, null, 'id');
+
+ $query = '
+SELECT user_id
+ FROM '.USER_INFOS_TABLE.'
+;';
+ $infos_users = query2array($query, null, 'user_id');
+
+ // users present in $base_users and not in $infos_users must be added
+ $to_create = array_diff($base_users, $infos_users);
+
+ if (count($to_create) > 0)
+ {
+ create_user_infos($to_create);
+ }
+
+ // users present in user related tables must be present in the base user
+ // table
+ $tables = array(
+ USER_MAIL_NOTIFICATION_TABLE,
+ USER_FEED_TABLE,
+ USER_INFOS_TABLE,
+ USER_ACCESS_TABLE,
+ USER_CACHE_TABLE,
+ USER_CACHE_CATEGORIES_TABLE,
+ USER_GROUP_TABLE
+ );
+
+ foreach ($tables as $table)
+ {
+ $query = '
+SELECT DISTINCT user_id
+ FROM '.$table.'
+;';
+ $to_delete = array_diff(
+ query2array($query, null, 'user_id'),
+ $base_users
+ );
+
+ if (count($to_delete) > 0)
+ {
+ $query = '
+DELETE
+ FROM '.$table.'
+ WHERE user_id in ('.implode(',', $to_delete).')
+;';
+ pwg_query($query);
+ }
+ }
+}
+
+/**
+ * Updates categories.uppercats field based on categories.id + categories.id_uppercat
+ */
+function update_uppercats()
+{
+ $query = '
+SELECT id, id_uppercat, uppercats
+ FROM '.CATEGORIES_TABLE.'
+;';
+ $cat_map = query2array($query, 'id');
+
+ $datas = array();
+ foreach ($cat_map as $id => $cat)
+ {
+ $upper_list = array();
+
+ $uppercat = $id;
+ while ($uppercat)
+ {
+ $upper_list[] = $uppercat;
+ $uppercat = $cat_map[$uppercat]['id_uppercat'];
+ }
+
+ $new_uppercats = implode(',', array_reverse($upper_list));
+ if ($new_uppercats != $cat['uppercats'])
+ {
+ $datas[] = array(
+ 'id' => $id,
+ 'uppercats' => $new_uppercats
+ );
+ }
+ }
+ $fields = array('primary' => array('id'), 'update' => array('uppercats'));
+ mass_updates(CATEGORIES_TABLE, $fields, $datas);
+}
+
+/**
+ * Update images.path field base on images.file and storage categories fulldirs.
+ */
+function update_path()
+{
+ $query = '
+SELECT DISTINCT(storage_category_id)
+ FROM '.IMAGES_TABLE.'
+ WHERE storage_category_id IS NOT NULL
+;';
+ $cat_ids = query2array($query, null, 'storage_category_id');
+ $fulldirs = get_fulldirs($cat_ids);
+
+ foreach ($cat_ids as $cat_id)
+ {
+ $query = '
+UPDATE '.IMAGES_TABLE.'
+ SET path = '.pwg_db_concat(array("'".$fulldirs[$cat_id]."/'",'file')).'
+ WHERE storage_category_id = '.$cat_id.'
+;';
+ pwg_query($query);
+ }
+}
+
+/**
+ * Change the parent category of the given categories. The categories are
+ * supposed virtual.
+ *
+ * @param int[] $category_ids
+ * @param int $new_parent (-1 for root)
+ */
+function move_categories($category_ids, $new_parent = -1)
+{
+ global $page;
+
+ if (count($category_ids) == 0)
+ {
+ return;
+ }
+
+ $new_parent = $new_parent < 1 ? 'NULL' : $new_parent;
+
+ $categories = array();
+
+ $query = '
+SELECT id, id_uppercat, status, uppercats
+ FROM '.CATEGORIES_TABLE.'
+ WHERE id IN ('.implode(',', $category_ids).')
+;';
+ $result = pwg_query($query);
+ while ($row = pwg_db_fetch_assoc($result))
+ {
+ $categories[$row['id']] =
+ array(
+ 'parent' => empty($row['id_uppercat']) ? 'NULL' : $row['id_uppercat'],
+ 'status' => $row['status'],
+ 'uppercats' => $row['uppercats']
+ );
+ }
+
+ // is the movement possible? The movement is impossible if you try to move
+ // a category in a sub-category or itself
+ if ('NULL' != $new_parent)
+ {
+ $query = '
+SELECT uppercats
+ FROM '.CATEGORIES_TABLE.'
+ WHERE id = '.$new_parent.'
+;';
+ list($new_parent_uppercats) = pwg_db_fetch_row(pwg_query($query));
+
+ foreach ($categories as $category)
+ {
+ // technically, you can't move a category with uppercats 12,125,13,14
+ // into a new parent category with uppercats 12,125,13,14,24
+ if (preg_match('/^'.$category['uppercats'].'(,|$)/', $new_parent_uppercats))
+ {
+ $page['errors'][] = l10n('You cannot move an album in its own sub album');
+ return;
+ }
+ }
+ }
+
+ $tables = array(
+ USER_ACCESS_TABLE => 'user_id',
+ GROUP_ACCESS_TABLE => 'group_id'
+ );
+
+ $query = '
+UPDATE '.CATEGORIES_TABLE.'
+ SET id_uppercat = '.$new_parent.'
+ WHERE id IN ('.implode(',', $category_ids).')
+;';
+ pwg_query($query);
+
+ update_uppercats();
+ update_global_rank();
+
+ // status and related permissions management
+ if ('NULL' == $new_parent)
+ {
+ $parent_status = 'public';
+ }
+ else
+ {
+ $query = '
+SELECT status
+ FROM '.CATEGORIES_TABLE.'
+ WHERE id = '.$new_parent.'
+;';
+ list($parent_status) = pwg_db_fetch_row(pwg_query($query));
+ }
+
+ if ('private' == $parent_status)
+ {
+ set_cat_status(array_keys($categories), 'private');
+ }
+
+ $page['infos'][] = l10n_dec(
+ '%d album moved', '%d albums moved',
+ count($categories)
+ );
+
+ pwg_activity('album', $category_ids, 'move', array('parent'=>$new_parent));
+}
+
+/**
+ * Create a virtual category.
+ *
+ * @param string $category_name
+ * @param int $parent_id
+ * @param array $options
+ * - boolean commentable
+ * - boolean visible
+ * - string status
+ * - string comment
+ * - boolean inherit
+ * @return array ('info', 'id') or ('error')
+ */
+function create_virtual_category($category_name, $parent_id=null, $options=array())
+{
+ global $conf, $user;
+
+ // is the given category name only containing blank spaces ?
+ if (preg_match('/^\s*$/', $category_name))
+ {
+ return array('error' => l10n('The name of an album must not be empty'));
+ }
+
+ $rank = 0;
+ if ('last' == $conf['newcat_default_position'])
+ {
+ //what is the current higher rank for this parent?
+ $query = '
+SELECT MAX(`rank`) AS max_rank
+ FROM '. CATEGORIES_TABLE .'
+ WHERE id_uppercat '.(empty($parent_id) ? 'IS NULL' : '= '.$parent_id).'
+;';
+ $row = pwg_db_fetch_assoc(pwg_query($query));
+
+ if (is_numeric($row['max_rank']))
+ {
+ $rank = $row['max_rank'] + 1;
+ }
+ }
+
+ $insert = array(
+ 'name' => $category_name,
+ 'rank' => $rank,
+ 'global_rank' => 0,
+ );
+
+ // is the album commentable?
+ if (isset($options['commentable']) and is_bool($options['commentable']))
+ {
+ $insert['commentable'] = $options['commentable'];
+ }
+ else
+ {
+ $insert['commentable'] = $conf['newcat_default_commentable'];
+ }
+ $insert['commentable'] = boolean_to_string($insert['commentable']);
+
+ // is the album temporarily locked? (only visible by administrators,
+ // whatever permissions) (may be overwritten if parent album is not
+ // visible)
+ if (isset($options['visible']) and is_bool($options['visible']))
+ {
+ $insert['visible'] = $options['visible'];
+ }
+ else
+ {
+ $insert['visible'] = $conf['newcat_default_visible'];
+ }
+ $insert['visible'] = boolean_to_string($insert['visible']);
+
+ // is the album private? (may be overwritten if parent album is private)
+ if (isset($options['status']) and 'private' == $options['status'])
+ {
+ $insert['status'] = 'private';
+ }
+ else
+ {
+ $insert['status'] = $conf['newcat_default_status'];
+ }
+
+ // any description for this album?
+ if (isset($options['comment']))
+ {
+ $insert['comment'] = $conf['allow_html_descriptions'] ? $options['comment'] : strip_tags($options['comment']);
+ }
+
+ if (!empty($parent_id) and is_numeric($parent_id))
+ {
+ $query = '
+SELECT id, uppercats, global_rank, visible, status
+ FROM '.CATEGORIES_TABLE.'
+ WHERE id = '.$parent_id.'
+;';
+ $parent = pwg_db_fetch_assoc(pwg_query($query));
+
+ $insert['id_uppercat'] = $parent['id'];
+ $insert['global_rank'] = $parent['global_rank'].'.'.$insert['rank'];
+
+ // at creation, must a category be visible or not ? Warning : if the
+ // parent category is invisible, the category is automatically create
+ // invisible. (invisible = locked)
+ if ('false' == $parent['visible'])
+ {
+ $insert['visible'] = 'false';
+ }
+
+ // at creation, must a category be public or private ? Warning : if the
+ // parent category is private, the category is automatically create
+ // private.
+ if ('private' == $parent['status'])
+ {
+ $insert['status'] = 'private';
+ }
+
+ $uppercats_prefix = $parent['uppercats'].',';
+ }
+ else
+ {
+ $uppercats_prefix = '';
+ }
+
+ // we have then to add the virtual category
+ single_insert(CATEGORIES_TABLE, $insert);
+ $inserted_id = pwg_db_insert_id(CATEGORIES_TABLE);
+
+ single_update(
+ CATEGORIES_TABLE,
+ array('uppercats' => $uppercats_prefix.$inserted_id),
+ array('id' => $inserted_id)
+ );
+
+ update_global_rank();
+
+ if ('private' == $insert['status'] and !empty($insert['id_uppercat']) and ((isset($options['inherit']) and $options['inherit']) or $conf['inheritance_by_default']) )
+ {
+ $query = '
+ SELECT group_id
+ FROM '.GROUP_ACCESS_TABLE.'
+ WHERE cat_id = '.$insert['id_uppercat'].'
+ ;';
+ $granted_grps = query2array($query, null, 'group_id');
+ $inserts = array();
+ foreach ($granted_grps as $granted_grp)
+ {
+ $inserts[] = array(
+ 'group_id' => $granted_grp,
+ 'cat_id' => $inserted_id
+ );
+ }
+ mass_inserts(GROUP_ACCESS_TABLE, array('group_id','cat_id'), $inserts);
+
+ $query = '
+ SELECT user_id
+ FROM '.USER_ACCESS_TABLE.'
+ WHERE cat_id = '.$insert['id_uppercat'].'
+ ;';
+ $granted_users = query2array($query, null, 'user_id');
+ add_permission_on_category($inserted_id, $granted_users);
+ }
+ elseif ('private' == $insert['status'])
+ {
+ add_permission_on_category($inserted_id, array_unique(array_merge(get_admins(), array($user['id']))));
+ }
+
+ trigger_notify('create_virtual_category', array_merge(array('id'=>$inserted_id), $insert));
+ pwg_activity('album', $inserted_id, 'add');
+
+ return array(
+ 'info' => l10n('Album added'),
+ 'id' => $inserted_id,
+ );
+}
+
+/**
+ * Set tags to an image.
+ * Warning: given tags are all tags associated to the image, not additionnal tags.
+ *
+ * @param int[] $tags
+ * @param int $image_id
+ */
+function set_tags($tags, $image_id)
+{
+ set_tags_of( array($image_id=>$tags) );
+}
+
+/**
+ * Add new tags to a set of images.
+ *
+ * @param int[] $tags
+ * @param int[] $images
+ */
+function add_tags($tags, $images)
+{
+ if (count($tags) == 0 or count($images) == 0)
+ {
+ return;
+ }
+
+ $taglist_before = get_image_tag_ids($images);
+
+ // we can't insert twice the same {image_id,tag_id} so we must first
+ // delete lines we'll insert later
+ $query = '
+DELETE
+ FROM '.IMAGE_TAG_TABLE.'
+ WHERE image_id IN ('.implode(',', $images).')
+ AND tag_id IN ('.implode(',', $tags).')
+;';
+ pwg_query($query);
+
+ $inserts = array();
+ foreach ($images as $image_id)
+ {
+ foreach ( array_unique($tags) as $tag_id)
+ {
+ $inserts[] = array(
+ 'image_id' => $image_id,
+ 'tag_id' => $tag_id,
+ );
+ }
+ }
+ mass_inserts(
+ IMAGE_TAG_TABLE,
+ array_keys($inserts[0]),
+ $inserts
+ );
+
+ $taglist_after = get_image_tag_ids($images);
+ $images_to_update = compare_image_tag_lists($taglist_before, $taglist_after);
+ update_images_lastmodified($images_to_update);
+
+ invalidate_user_cache_nb_tags();
+}
+
+/**
+ * Delete tags and tags associations.
+ *
+ * @param int[] $tag_ids
+ */
+function delete_tags($tag_ids)
+{
+ if (is_numeric($tag_ids))
+ {
+ $tag_ids = array($tag_ids);
+ }
+
+ if (!is_array($tag_ids))
+ {
+ return false;
+ }
+
+ // we need the list of impacted images, to update their lastmodified
+ $query = '
+SELECT
+ image_id
+ FROM '.IMAGE_TAG_TABLE.'
+ WHERE tag_id IN ('.implode(',', $tag_ids).')
+;';
+ $image_ids = query2array($query, null, 'image_id');
+
+ $query = '
+DELETE
+ FROM '.IMAGE_TAG_TABLE.'
+ WHERE tag_id IN ('.implode(',', $tag_ids).')
+;';
+ pwg_query($query);
+
+ $query = '
+DELETE
+ FROM '.TAGS_TABLE.'
+ WHERE id IN ('.implode(',', $tag_ids).')
+;';
+ pwg_query($query);
+
+ trigger_notify("delete_tags", $tag_ids);
+ pwg_activity('tag', $tag_ids, 'delete');
+
+ update_images_lastmodified($image_ids);
+ invalidate_user_cache_nb_tags();
+}
+
+/**
+ * Returns a tag id from its name. If nothing found, create a new tag.
+ *
+ * @param string $tag_name
+ * @return int
+ */
+function tag_id_from_tag_name($tag_name)
+{
+ global $page;
+
+ $tag_name = trim($tag_name);
+ if (isset($page['tag_id_from_tag_name_cache'][$tag_name]))
+ {
+ return $page['tag_id_from_tag_name_cache'][$tag_name];
+ }
+
+ // search existing by exact name
+ $query = '
+SELECT id
+ FROM '.TAGS_TABLE.'
+ WHERE name = \''.$tag_name.'\'
+;';
+ if (count($existing_tags = query2array($query, null, 'id')) == 0)
+ {
+ $url_name = trigger_change('render_tag_url', $tag_name);
+ // search existing by url name
+ $query = '
+SELECT id
+ FROM '.TAGS_TABLE.'
+ WHERE url_name = \''.$url_name.'\'
+;';
+ if (count($existing_tags = query2array($query, null, 'id')) == 0)
+ {
+ // search by extended description (plugin sub name)
+ $sub_name_where = trigger_change('get_tag_name_like_where', array(), $tag_name);
+ if (count($sub_name_where))
+ {
+ $query = '
+SELECT id
+ FROM '.TAGS_TABLE.'
+ WHERE '.implode(' OR ', $sub_name_where).'
+;';
+ $existing_tags = query2array($query, null, 'id');
+ }
+
+ if (count($existing_tags) == 0)
+ {// finally create the tag
+ mass_inserts(
+ TAGS_TABLE,
+ array('name', 'url_name'),
+ array(
+ array(
+ 'name' => $tag_name,
+ 'url_name' => $url_name,
+ )
+ )
+ );
+
+ $page['tag_id_from_tag_name_cache'][$tag_name] = pwg_db_insert_id(TAGS_TABLE);
+
+ invalidate_user_cache_nb_tags();
+
+ return $page['tag_id_from_tag_name_cache'][$tag_name];
+ }
+ }
+ }
+
+ $page['tag_id_from_tag_name_cache'][$tag_name] = $existing_tags[0];
+ return $page['tag_id_from_tag_name_cache'][$tag_name];
+}
+
+/**
+ * Set tags of images. Overwrites all existing associations.
+ *
+ * @param array $tags_of - keys are image ids, values are array of tag ids
+ */
+function set_tags_of($tags_of)
+{
+ if (count($tags_of) > 0)
+ {
+ $taglist_before = get_image_tag_ids(array_keys($tags_of));
+ global $logger; $logger->debug('taglist_before', $taglist_before);
+
+ $query = '
+DELETE
+ FROM '.IMAGE_TAG_TABLE.'
+ WHERE image_id IN ('.implode(',', array_keys($tags_of)).')
+;';
+ pwg_query($query);
+
+ $inserts = array();
+
+ foreach ($tags_of as $image_id => $tag_ids)
+ {
+ foreach (array_unique($tag_ids) as $tag_id)
+ {
+ $inserts[] = array(
+ 'image_id' => $image_id,
+ 'tag_id' => $tag_id,
+ );
+ }
+ }
+
+ if (count($inserts))
+ {
+ mass_inserts(
+ IMAGE_TAG_TABLE,
+ array_keys($inserts[0]),
+ $inserts
+ );
+ }
+
+ $taglist_after = get_image_tag_ids(array_keys($tags_of));
+ global $logger; $logger->debug('taglist_after', $taglist_after);
+ $images_to_update = compare_image_tag_lists($taglist_before, $taglist_after);
+ global $logger; $logger->debug('$images_to_update', $images_to_update);
+
+ update_images_lastmodified($images_to_update);
+ invalidate_user_cache_nb_tags();
+ }
+}
+
+/**
+ * Get list of tag ids for each image. Returns an empty list if the image has
+ * no tags.
+ *
+ * @since 2.9
+ * @param array $image_ids
+ * @return associative array, image_id => list of tag ids
+ */
+function get_image_tag_ids($image_ids)
+{
+ if (!is_array($image_ids) and is_int($image_ids))
+ {
+ $images_ids = array($image_ids);
+ }
+
+ if (count($image_ids) == 0)
+ {
+ return array();
+ }
+
+ $query = '
+SELECT
+ image_id,
+ tag_id
+ FROM '.IMAGE_TAG_TABLE.'
+ WHERE image_id IN ('.implode(',', $image_ids).')
+;';
+
+ $tags_of = array_fill_keys($image_ids, array());
+ $image_tags = query2array($query);
+ foreach ($image_tags as $image_tag)
+ {
+ $tags_of[ $image_tag['image_id'] ][] = $image_tag['tag_id'];
+ }
+
+ return $tags_of;
+}
+
+/**
+ * Compare the list of tags, for each image. Returns image_ids where tag list has changed.
+ *
+ * @since 2.9
+ * @param array $taglist_before - for each image_id (key), list of tag ids
+ * @param array $taglist_after - for each image_id (key), list of tag ids
+ * @return array - image_ids where the list has changed
+ */
+function compare_image_tag_lists($taglist_before, $taglist_after)
+{
+ $images_to_update = array();
+
+ foreach ($taglist_after as $image_id => $list_after)
+ {
+ sort($list_after);
+
+ $list_before = isset($taglist_before[$image_id]) ? $taglist_before[$image_id] : array();
+ sort($list_before);
+
+ if ($list_after != $list_before)
+ {
+ $images_to_update[] = $image_id;
+ }
+ }
+
+ return $images_to_update;
+}
+
+/**
+ * Instead of associating images to categories, add them in the lounge, waiting for take-off.
+ *
+ * @since 12
+ * @param array $images - list of image ids
+ * @param array $categories - list of category ids
+ */
+function fill_lounge($images, $categories)
+{
+ $inserts = array();
+ foreach ($categories as $category_id)
+ {
+ foreach ($images as $image_id)
+ {
+ $inserts[] = array(
+ 'image_id' => $image_id,
+ 'category_id' => $category_id,
+ );
+ }
+ }
+
+ if (count($inserts))
+ {
+ mass_inserts(
+ LOUNGE_TABLE,
+ array_keys($inserts[0]),
+ $inserts,
+ array('ignore'=>true)
+ );
+ }
+}
+
+/**
+ * Move images from the lounge to the categories they were intended for.
+ *
+ * @since 12
+ * @param boolean $invalidate_user_cache
+ * @return int number of images moved
+ */
+function empty_lounge($invalidate_user_cache=true)
+{
+ global $logger, $conf;
+
+ if (isset($conf['empty_lounge_running']))
+ {
+ list($running_exec_id, $running_exec_start_time) = explode('-', $conf['empty_lounge_running']);
+ if (time() - $running_exec_start_time > 60)
+ {
+ $logger->debug(__FUNCTION__.', exec='.$running_exec_id.', timeout stopped by another call to the function');
+ conf_delete_param('empty_lounge_running');
+ }
+ }
+
+ $exec_id = generate_key(4);
+ $logger->debug(__FUNCTION__.(isset($_REQUEST['method']) ? ' (API:'.$_REQUEST['method'].')' : '').', exec='.$exec_id.', begins');
+
+ // if lounge is already being emptied, skip
+ $query = '
+INSERT IGNORE
+ INTO '.CONFIG_TABLE.'
+ SET param="empty_lounge_running"
+ , value="'.$exec_id.'-'.time().'"
+;';
+ pwg_query($query);
+
+ list($empty_lounge_running) = pwg_db_fetch_row(pwg_query('SELECT value FROM '.CONFIG_TABLE.' WHERE param = "empty_lounge_running"'));
+ list($running_exec_id,) = explode('-', $empty_lounge_running);
+
+ if ($running_exec_id != $exec_id)
+ {
+ $logger->debug(__FUNCTION__.', exec='.$exec_id.', skip');
+ return;
+ }
+ $logger->debug(__FUNCTION__.', exec='.$exec_id.' wins the race and gets the token!');
+
+ $max_image_id = 0;
+
+ $query = '
+SELECT
+ image_id,
+ category_id
+ FROM '.LOUNGE_TABLE.'
+ ORDER BY category_id ASC, image_id ASC
+;';
+
+ $rows = query2array($query);
+
+ $images = array();
+ foreach ($rows as $idx => $row)
+ {
+ if ($row['image_id'] > $max_image_id)
+ {
+ $max_image_id = $row['image_id'];
+ }
+
+ $images[] = $row['image_id'];
+
+ if (!isset($rows[$idx+1]) or $rows[$idx+1]['category_id'] != $row['category_id'])
+ {
+ // if we're at the end of the loop OR if category changes
+ associate_images_to_categories($images, array($row['category_id']));
+ $images = array();
+ }
+ }
+
+ $query = '
+DELETE
+ FROM '.LOUNGE_TABLE.'
+ WHERE image_id <= '.$max_image_id.'
+;';
+ pwg_query($query);
+
+ if ($invalidate_user_cache)
+ {
+ invalidate_user_cache();
+ }
+
+ conf_delete_param('empty_lounge_running');
+
+ $logger->debug(__FUNCTION__.', exec='.$exec_id.', ends');
+
+ trigger_notify('empty_lounge', $rows);
+
+ return $rows;
+}
+
+/**
+ * Associate a list of images to a list of categories.
+ * The function will not duplicate links and will preserve ranks.
+ *
+ * @param int[] $images
+ * @param int[] $categories
+ */
+function associate_images_to_categories($images, $categories)
+{
+ if (count($images) == 0
+ or count($categories) == 0)
+ {
+ return false;
+ }
+
+ // get existing associations
+ $query = '
+SELECT
+ image_id,
+ category_id
+ FROM '.IMAGE_CATEGORY_TABLE.'
+ WHERE image_id IN ('.implode(',', $images).')
+ AND category_id IN ('.implode(',', $categories).')
+;';
+ $result = pwg_query($query);
+
+ $existing = array();
+ while ($row = pwg_db_fetch_assoc($result))
+ {
+ $existing[ $row['category_id'] ][] = $row['image_id'];
+ }
+
+ // get max rank of each categories
+ $query = '
+SELECT
+ category_id,
+ MAX(`rank`) AS max_rank
+ FROM '.IMAGE_CATEGORY_TABLE.'
+ WHERE `rank` IS NOT NULL
+ AND category_id IN ('.implode(',', $categories).')
+ GROUP BY category_id
+;';
+
+ $current_rank_of = query2array(
+ $query,
+ 'category_id',
+ 'max_rank'
+ );
+
+ // associate only not already associated images
+ $inserts = array();
+ foreach ($categories as $category_id)
+ {
+ if (!isset($current_rank_of[$category_id]))
+ {
+ $current_rank_of[$category_id] = 0;
+ }
+ if (!isset($existing[$category_id]))
+ {
+ $existing[$category_id] = array();
+ }
+
+ foreach ($images as $image_id)
+ {
+ if (!in_array($image_id, $existing[$category_id]))
+ {
+ $rank = ++$current_rank_of[$category_id];
+
+ $inserts[] = array(
+ 'image_id' => $image_id,
+ 'category_id' => $category_id,
+ 'rank' => $rank,
+ );
+ }
+ }
+ }
+
+ if (count($inserts))
+ {
+ mass_inserts(
+ IMAGE_CATEGORY_TABLE,
+ array_keys($inserts[0]),
+ $inserts
+ );
+
+ update_category($categories);
+ }
+}
+
+/**
+ * Dissociate a list of images from a category.
+ *
+ * @param int[] $images
+ * @param int $categories
+ */
+function dissociate_images_from_category($images, $category)
+{
+ // physical links must not be broken, so we must first retrieve image_id
+ // which create virtual links with the category to "dissociate from".
+ $query = '
+SELECT id
+ FROM '.IMAGE_CATEGORY_TABLE.'
+ INNER JOIN '.IMAGES_TABLE.' ON image_id = id
+ WHERE category_id ='.$category.'
+ AND id IN ('.implode(',', $images).')
+ AND (
+ category_id != storage_category_id
+ OR storage_category_id IS NULL
+ )
+;';
+ $dissociables = array_from_query($query, 'id');
+
+ if (!empty($dissociables))
+ {
+ $query = '
+DELETE
+ FROM '.IMAGE_CATEGORY_TABLE.'
+ WHERE category_id = '.$category.'
+ AND image_id IN ('.implode(',', $dissociables).')
+';
+ pwg_query($query);
+ }
+
+ return count($dissociables);
+}
+
+/**
+ * Dissociate images from all old categories except their storage category and
+ * associate to new categories.
+ * This function will preserve ranks.
+ *
+ * @param int[] $images
+ * @param int[] $categories
+ */
+function move_images_to_categories($images, $categories)
+{
+ if (count($images) == 0)
+ {
+ return false;
+ }
+
+ // let's first break links with all old albums but their "storage album"
+ $query = '
+DELETE '.IMAGE_CATEGORY_TABLE.'.*
+ FROM '.IMAGE_CATEGORY_TABLE.'
+ JOIN '.IMAGES_TABLE.' ON image_id=id
+ WHERE id IN ('.implode(',', $images).')
+';
+
+ if (is_array($categories) and count($categories) > 0)
+ {
+ $query.= '
+ AND category_id NOT IN ('.implode(',', $categories).')
+';
+ }
+
+ $query.= '
+ AND (storage_category_id IS NULL OR storage_category_id != category_id)
+;';
+ pwg_query($query);
+
+ if (is_array($categories) and count($categories) > 0)
+ {
+ associate_images_to_categories($images, $categories);
+ }
+}
+
+/**
+ * Associate images associated to a list of source categories to a list of
+ * destination categories.
+ *
+ * @param int[] $sources
+ * @param int[] $destinations
+ */
+function associate_categories_to_categories($sources, $destinations)
+{
+ if (count($sources) == 0)
+ {
+ return false;
+ }
+
+ $query = '
+SELECT image_id
+ FROM '.IMAGE_CATEGORY_TABLE.'
+ WHERE category_id IN ('.implode(',', $sources).')
+;';
+ $images = query2array($query, null, 'image_id');
+
+ associate_images_to_categories($images, $destinations);
+}
+
+/**
+ * Refer main Piwigo URLs (currently PHPWG_DOMAIN domain)
+ *
+ * @return string[]
+ */
+function pwg_URL()
+{
+ $urls = array(
+ 'HOME' => PHPWG_URL,
+ 'WIKI' => PHPWG_URL.'/doc',
+ 'DEMO' => PHPWG_URL.'/demo',
+ 'FORUM' => PHPWG_URL.'/forum',
+ 'BUGS' => PHPWG_URL.'/bugs',
+ 'EXTENSIONS' => PHPWG_URL.'/ext',
+ );
+ return $urls;
+}
+
+/**
+ * Invalidates cached data (permissions and category counts) for all users.
+ */
+function invalidate_user_cache($full = true)
+{
+ global $persistent_cache, $logger;
+
+ if (isset($logger) and gettype($logger) == 'object' and get_class($logger) == 'Logger')
+ {
+ $logger->info(__FUNCTION__.' called');
+ }
+
+ if ($full)
+ {
+ $query = '
+TRUNCATE TABLE '.USER_CACHE_CATEGORIES_TABLE.';';
+ pwg_query($query);
+ $query = '
+TRUNCATE TABLE '.USER_CACHE_TABLE.';';
+ pwg_query($query);
+ }
+ else
+ {
+ $query = '
+UPDATE '.USER_CACHE_TABLE.'
+ SET need_update = \'true\';';
+ pwg_query($query);
+ }
+ $persistent_cache->purge(true);
+ conf_delete_param('count_orphans');
+ trigger_notify('invalidate_user_cache', $full);
+}
+
+/**
+ * Invalidates cached tags counter for all users.
+ */
+function invalidate_user_cache_nb_tags()
+{
+ global $user;
+ unset($user['nb_available_tags']);
+
+ $query = '
+UPDATE '.USER_CACHE_TABLE.'
+ SET nb_available_tags = NULL';
+ pwg_query($query);
+}
+
+/**
+ * Adds the caracter set to a create table sql query.
+ * All CREATE TABLE queries must call this function
+ *
+ * @param string $query
+ * @return string
+ */
+function create_table_add_character_set($query)
+{
+ defined('DB_CHARSET') or fatal_error('create_table_add_character_set DB_CHARSET undefined');
+ if ('DB_CHARSET'!='')
+ {
+ if ( version_compare(pwg_get_db_version(), '4.1.0', '<') )
+ {
+ return $query;
+ }
+ $charset_collate = " DEFAULT CHARACTER SET ".DB_CHARSET;
+ if (DB_COLLATE!='')
+ {
+ $charset_collate .= " COLLATE ".DB_COLLATE;
+ }
+ if ( is_array($query) )
+ {
+ foreach( $query as $id=>$q)
+ {
+ $q=trim($q);
+ $q=trim($q, ';');
+ if (preg_match('/^CREATE\s+TABLE/i',$q))
+ {
+ $q.=$charset_collate;
+ }
+ $q .= ';';
+ $query[$id] = $q;
+ }
+ }
+ else
+ {
+ $query=trim($query);
+ $query=trim($query, ';');
+ if (preg_match('/^CREATE\s+TABLE/i',$query))
+ {
+ $query.=$charset_collate;
+ }
+ $query .= ';';
+ }
+ }
+ return $query;
+}
+
+/**
+ * Returns access levels as array used on template with html_options functions.
+ *
+ * @param int $MinLevelAccess
+ * @param int $MaxLevelAccess
+ * @return array
+ */
+function get_user_access_level_html_options($MinLevelAccess = ACCESS_FREE, $MaxLevelAccess = ACCESS_CLOSED)
+{
+ $tpl_options = array();
+ for ($level = $MinLevelAccess; $level <= $MaxLevelAccess; $level++)
+ {
+ $tpl_options[$level] = l10n(sprintf('ACCESS_%d', $level));
+ }
+ return $tpl_options;
+}
+
+/**
+ * returns a list of templates currently available in template-extension.
+ * Each .tpl file is extracted from template-extension.
+ *
+ * @param string $start (internal use)
+ * @return string[]
+ */
+function get_extents($start='')
+{
+ if ($start == '') { $start = './template-extension'; }
+ $dir = opendir($start);
+ $extents = array();
+
+ while (($file = readdir($dir)) !== false)
+ {
+ if ( $file == '.' or $file == '..' or $file == '.svn') continue;
+ $path = $start . '/' . $file;
+ if (is_dir($path))
+ {
+ $extents = array_merge($extents, get_extents($path));
+ }
+ elseif ( !is_link($path) and file_exists($path)
+ and get_extension($path) == 'tpl' )
+ {
+ $extents[] = substr($path, 21);
+ }
+ }
+ return $extents;
+}
+
+/**
+ * Create a new tag.
+ *
+ * @param string $tag_name
+ * @return array ('id', info') or ('error')
+ */
+function create_tag($tag_name)
+{
+ // clean the tag, no html/js allowed in tag name
+ $tag_name = strip_tags($tag_name);
+
+ // does the tag already exists?
+ $query = '
+SELECT id
+ FROM '.TAGS_TABLE.'
+ WHERE name = \''.$tag_name.'\'
+;';
+ $existing_tags = query2array($query, null, 'id');
+
+ if (count($existing_tags) == 0)
+ {
+ single_insert(
+ TAGS_TABLE,
+ array(
+ 'name' => $tag_name,
+ 'url_name' => trigger_change('render_tag_url', $tag_name),
+ )
+ );
+
+ $inserted_id = pwg_db_insert_id(TAGS_TABLE);
+
+ return array(
+ 'info' => l10n('Tag "%s" was added', stripslashes($tag_name)),
+ 'id' => $inserted_id,
+ );
+ }
+ else
+ {
+ return array(
+ 'error' => l10n('Tag "%s" already exists', stripslashes($tag_name))
+ );
+ }
+}
+
+/**
+ * Is the category accessible to the (Admin) user ?
+ * Note : if the user is not authorized to see this category, category jump
+ * will be replaced by admin cat_modify page
+ *
+ * @param int $category_id
+ * @return bool
+ */
+function cat_admin_access($category_id)
+{
+ global $user;
+
+ // $filter['visible_categories'] and $filter['visible_images']
+ // are not used because it's not necessary (filter <> restriction)
+ if (in_array($category_id, @explode(',', $user['forbidden_categories'])))
+ {
+ return false;
+ }
+ return true;
+}
+
+/**
+ * Retrieve data from external URL.
+ *
+ * @param string $src
+ * @param string|Ressource $dest - can be a file ressource or string
+ * @param array $get_data - data added to request url
+ * @param array $post_data - data transmitted with POST
+ * @param string $user_agent
+ * @param int $step (internal use)
+ * @return bool
+ */
+function fetchRemote($src, &$dest, $get_data=array(), $post_data=array(), $user_agent='Piwigo', $step=0)
+{
+ global $conf;
+
+ // Try to retrieve data from local file?
+ if (!url_is_remote($src))
+ {
+ $content = @file_get_contents($src);
+ if ($content !== false)
+ {
+ is_resource($dest) ? @fwrite($dest, $content) : $dest = $content;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ // After 3 redirections, return false
+ if ($step > 3) return false;
+
+ // Initialization
+ $method = empty($post_data) ? 'GET' : 'POST';
+ $request = empty($post_data) ? '' : http_build_query($post_data, '', '&');
+ if (!empty($get_data))
+ {
+ $src .= strpos($src, '?') === false ? '?' : '&';
+ $src .= http_build_query($get_data, '', '&');
+ }
+
+ // Initialize $dest
+ is_resource($dest) or $dest = '';
+
+ // Try curl to read remote file
+ // TODO : remove all these @
+ if (function_exists('curl_init') && function_exists('curl_exec'))
+ {
+ $ch = @curl_init();
+
+ if (isset($conf['use_proxy']) && $conf['use_proxy'])
+ {
+ @curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 0);
+ @curl_setopt($ch, CURLOPT_PROXY, $conf['proxy_server']);
+ if (isset($conf['proxy_auth']) && !empty($conf['proxy_auth']))
+ {
+ @curl_setopt($ch, CURLOPT_PROXYUSERPWD, $conf['proxy_auth']);
+ }
+ }
+
+ @curl_setopt($ch, CURLOPT_URL, $src);
+ @curl_setopt($ch, CURLOPT_HEADER, 1);
+ @curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
+ @curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ if ($method == 'POST')
+ {
+ @curl_setopt($ch, CURLOPT_POST, 1);
+ @curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
+ }
+ $content = @curl_exec($ch);
+ $header_length = @curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+ $status = @curl_getinfo($ch, CURLINFO_HTTP_CODE);
+ @curl_close($ch);
+ if ($content !== false and $status >= 200 and $status < 400)
+ {
+ if (preg_match('/Location:\s+?(.+)/', substr($content, 0, $header_length), $m))
+ {
+ return fetchRemote($m[1], $dest, array(), array(), $user_agent, $step+1);
+ }
+ $content = substr($content, $header_length);
+ is_resource($dest) ? @fwrite($dest, $content) : $dest = $content;
+ return true;
+ }
+ }
+
+ // Try file_get_contents to read remote file
+ if (ini_get('allow_url_fopen'))
+ {
+ $opts = array(
+ 'http' => array(
+ 'method' => $method,
+ 'user_agent' => $user_agent,
+ )
+ );
+ if ($method == 'POST')
+ {
+ $opts['http']['content'] = $request;
+ }
+ $context = @stream_context_create($opts);
+ $content = @file_get_contents($src, false, $context);
+ if ($content !== false)
+ {
+ is_resource($dest) ? @fwrite($dest, $content) : $dest = $content;
+ return true;
+ }
+ }
+
+ // Try fsockopen to read remote file
+ $src = parse_url($src);
+ $host = $src['host'];
+ $path = isset($src['path']) ? $src['path'] : '/';
+ $path .= isset($src['query']) ? '?'.$src['query'] : '';
+
+ if (($s = @fsockopen($host,80,$errno,$errstr,5)) === false)
+ {
+ return false;
+ }
+
+ $http_request = $method." ".$path." HTTP/1.0\r\n";
+ $http_request .= "Host: ".$host."\r\n";
+ if ($method == 'POST')
+ {
+ $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n";
+ $http_request .= "Content-Length: ".strlen($request)."\r\n";
+ }
+ $http_request .= "User-Agent: ".$user_agent."\r\n";
+ $http_request .= "Accept: */*\r\n";
+ $http_request .= "\r\n";
+ $http_request .= $request;
+
+ fwrite($s, $http_request);
+
+ $i = 0;
+ $in_content = false;
+ while (!feof($s))
+ {
+ $line = fgets($s);
+
+ if (rtrim($line,"\r\n") == '' && !$in_content)
+ {
+ $in_content = true;
+ $i++;
+ continue;
+ }
+ if ($i == 0)
+ {
+ if (!preg_match('/HTTP\/(\\d\\.\\d)\\s*(\\d+)\\s*(.*)/',rtrim($line,"\r\n"), $m))
+ {
+ fclose($s);
+ return false;
+ }
+ $status = (int) $m[2];
+ if ($status < 200 || $status >= 400)
+ {
+ fclose($s);
+ return false;
+ }
+ }
+ if (!$in_content)
+ {
+ if (preg_match('/Location:\s+?(.+)$/',rtrim($line,"\r\n"),$m))
+ {
+ fclose($s);
+ return fetchRemote(trim($m[1]),$dest,array(),array(),$user_agent,$step+1);
+ }
+ $i++;
+ continue;
+ }
+ is_resource($dest) ? @fwrite($dest, $line) : $dest .= $line;
+ $i++;
+ }
+ fclose($s);
+ return true;
+}
+
+/**
+ * Returns the groupname corresponding to the given group identifier if exists.
+ *
+ * @param int $group_id
+ * @return string|false
+ */
+function get_groupname($group_id)
+{
+ $query = '
+SELECT name
+ FROM `'.GROUPS_TABLE.'`
+ WHERE id = '.intval($group_id).'
+;';
+ $result = pwg_query($query);
+ if (pwg_db_num_rows($result) > 0)
+ {
+ list($groupname) = pwg_db_fetch_row($result);
+ }
+ else
+ {
+ return false;
+ }
+
+ return $groupname;
+}
+
+function delete_groups($group_ids)
+{
+
+ if (count($group_ids) == 0)
+ {
+ trigger_error('There is no group to delete', E_USER_WARNING);
+ return false;
+ }
+
+ if (preg_match('/^group:(\d+)$/', conf_get_param('email_admin_on_new_user', 'undefined'), $matches))
+ {
+ foreach ($group_ids as $group_id)
+ {
+ if ($group_id == $matches[1])
+ {
+ conf_update_param('email_admin_on_new_user', 'all', true);
+ }
+ }
+ }
+
+ $group_id_string = implode(',', $group_ids);
+
+ // destruction of the access linked to the group
+ $query = '
+DELETE
+ FROM '. GROUP_ACCESS_TABLE .'
+ WHERE group_id IN ('. $group_id_string .')
+;';
+ pwg_query($query);
+
+ // destruction of the users links for this group
+ $query = '
+DELETE
+ FROM '. USER_GROUP_TABLE .'
+ WHERE group_id IN ('. $group_id_string .')
+;';
+ pwg_query($query);
+
+ $query = '
+SELECT id, name
+ FROM `'. GROUPS_TABLE .'`
+ WHERE id IN ('. $group_id_string .')
+;';
+
+ $group_list = query2array($query, 'id', 'name');
+ $groupids = array_keys($group_list);
+
+ // destruction of the group
+ $query = '
+DELETE
+ FROM `'. GROUPS_TABLE .'`
+ WHERE id IN ('. $group_id_string .')
+;';
+ pwg_query($query);
+
+ trigger_notify('delete_group', $groupids);
+ pwg_activity('group', $groupids, 'delete');
+
+
+ return $group_list;
+}
+
+/**
+ * Returns the username corresponding to the given user identifier if exists.
+ *
+ * @param int $user_id
+ * @return string|false
+ */
+function get_username($user_id)
+{
+ global $conf;
+
+ $query = '
+SELECT '.$conf['user_fields']['username'].'
+ FROM '.USERS_TABLE.'
+ WHERE '.$conf['user_fields']['id'].' = '.intval($user_id).'
+;';
+ $result = pwg_query($query);
+ if (pwg_db_num_rows($result) > 0)
+ {
+ list($username) = pwg_db_fetch_row($result);
+ }
+ else
+ {
+ return false;
+ }
+
+ return stripslashes($username);
+}
+
+/**
+ * Get url on piwigo.org for newsletter subscription
+ *
+ * @param string $language (unused)
+ * @return string
+ */
+function get_newsletter_subscribe_base_url($language='en_UK')
+{
+ return PHPWG_URL.'/announcement/subscribe/';
+}
+
+/**
+ * Get url on piwigo.org for old newsletters
+ *
+ * @param string $language (unused)
+ * @return string
+ */
+function get_old_newsletters_base_url($language='en_UK')
+{
+ return PHPWG_URL.'/newsletter';
+}
+
+/**
+ * Return admin menu id for accordion.
+ *
+ * @param string $menu_page
+ * @return int
+ */
+function get_active_menu($menu_page)
+{
+ global $page;
+
+ if (isset($page['active_menu']))
+ {
+ return $page['active_menu'];
+ }
+
+ switch ($menu_page)
+ {
+ case 'photo':
+ case 'photos_add':
+ case 'rating':
+ case 'tags':
+ case 'batch_manager':
+ return 0;
+
+ case 'album':
+ case 'cat_list':
+ case 'albums':
+ case 'cat_options':
+ case 'cat_search':
+ case 'permalinks':
+ return 1;
+
+ case 'user_list':
+ case 'user_perm':
+ case 'group_list':
+ case 'group_perm':
+ case 'notification_by_mail':
+ case 'user_activity';
+ return 2;
+
+ case 'site_manager':
+ case 'site_update':
+ case 'stats':
+ case 'history':
+ case 'maintenance':
+ case 'comments':
+ case 'updates':
+ return 3;
+
+ case 'configuration':
+ case 'derivatives':
+ case 'extend_for_templates':
+ case 'menubar':
+ case 'themes':
+ case 'theme':
+ case 'languages':
+ return 4;
+
+ default:
+ return -1;
+ }
+}
+
+/**
+ * Get tags list from SQL query (ids are surrounded by ~~, for get_tag_ids()).
+ *
+ * @param string $query
+ * @param boolean $only_user_language - if true, only local name is returned for
+ * multilingual tags (if ExtendedDescription plugin is active)
+ * @return array[] ('id', 'name')
+ */
+function get_taglist($query, $only_user_language=true)
+{
+ $result = pwg_query($query);
+
+ $taglist = array();
+ $altlist = array();
+ while ($row = pwg_db_fetch_assoc($result))
+ {
+ $raw_name = $row['name'];
+ $name = trigger_change('render_tag_name', $raw_name, $row);
+
+ $taglist[] = array(
+ 'name' => $name,
+ 'id' => '~~'.$row['id'].'~~',
+ );
+
+ if (!$only_user_language)
+ {
+ $alt_names = trigger_change('get_tag_alt_names', array(), $raw_name);
+
+ foreach( array_diff( array_unique($alt_names), array($name) ) as $alt)
+ {
+ $altlist[] = array(
+ 'name' => $alt,
+ 'id' => '~~'.$row['id'].'~~',
+ );
+ }
+ }
+ }
+
+ usort($taglist, 'tag_alpha_compare');
+ if (count($altlist))
+ {
+ usort($altlist, 'tag_alpha_compare');
+ $taglist = array_merge($taglist, $altlist);
+ }
+
+ return $taglist;
+}
+
+/**
+ * Get tags ids from a list of raw tags (existing tags or new tags).
+ *
+ * In $raw_tags we receive something like array('~~6~~', '~~59~~', 'New
+ * tag', 'Another new tag') The ~~34~~ means that it is an existing
+ * tag. We added the surrounding ~~ to permit creation of tags like "10"
+ * or "1234" (numeric characters only)
+ *
+ * @param string|string[] $raw_tags - array or comma separated string
+ * @param boolean $allow_create
+ * @return int[]
+ */
+function get_tag_ids($raw_tags, $allow_create=true)
+{
+ $tag_ids = array();
+ if (!is_array($raw_tags))
+ {
+ $raw_tags = explode(',',$raw_tags);
+ }
+
+ foreach ($raw_tags as $raw_tag)
+ {
+ if (preg_match('/^~~(\d+)~~$/', $raw_tag, $matches))
+ {
+ $tag_ids[] = $matches[1];
+ }
+ elseif ($allow_create)
+ {
+ // we have to create a new tag
+ $tag_ids[] = tag_id_from_tag_name(strip_tags($raw_tag));
+ }
+ }
+
+ return $tag_ids;
+}
+
+/**
+ * Returns the argument_ids array with new sequenced keys based on related
+ * names. Sequence is not case sensitive.
+ * Warning: By definition, this function breaks original keys.
+ *
+ * @param int[] $elements_ids
+ * @param string[] $name - names of elements, indexed by ids
+ * @return int[]
+ */
+function order_by_name($element_ids, $name)
+{
+ $ordered_element_ids = array();
+ foreach ($element_ids as $k_id => $element_id)
+ {
+ $key = strtolower($name[$element_id]) .'-'. $name[$element_id] .'-'. $k_id;
+ $ordered_element_ids[$key] = $element_id;
+ }
+ ksort($ordered_element_ids);
+ return $ordered_element_ids;
+}
+
+/**
+ * Grant access to a list of categories for a list of users.
+ *
+ * @param int[] $category_ids
+ * @param int[] $user_ids
+ */
+function add_permission_on_category($category_ids, $user_ids)
+{
+ if (!is_array($category_ids))
+ {
+ $category_ids = array($category_ids);
+ }
+ if (!is_array($user_ids))
+ {
+ $user_ids = array($user_ids);
+ }
+
+ // check for emptiness
+ if (count($category_ids) == 0 or count($user_ids) == 0)
+ {
+ return;
+ }
+
+ // make sure categories are private and select uppercats or subcats
+ $cat_ids = get_uppercat_ids($category_ids);
+ if (isset($_POST['apply_on_sub']))
+ {
+ $cat_ids = array_merge($cat_ids, get_subcat_ids($category_ids));
+ }
+
+ $query = '
+SELECT id
+ FROM '.CATEGORIES_TABLE.'
+ WHERE id IN ('.implode(',', $cat_ids).')
+ AND status = \'private\'
+;';
+ $private_cats = query2array($query, null, 'id');
+
+ if (count($private_cats) == 0)
+ {
+ return;
+ }
+
+ $inserts = array();
+ foreach ($private_cats as $cat_id)
+ {
+ foreach ($user_ids as $user_id)
+ {
+ $inserts[] = array(
+ 'user_id' => $user_id,
+ 'cat_id' => $cat_id
+ );
+ }
+ }
+
+ mass_inserts(
+ USER_ACCESS_TABLE,
+ array('user_id','cat_id'),
+ $inserts,
+ array('ignore'=>true)
+ );
+}
+
+/**
+ * Returns the list of admin users.
+ *
+ * @param boolean $include_webmaster
+ * @return int[]
+ */
+function get_admins($include_webmaster=true)
+{
+ $status_list = array('admin');
+
+ if ($include_webmaster)
+ {
+ $status_list[] = 'webmaster';
+ }
+
+ $query = '
+SELECT
+ user_id
+ FROM '.USER_INFOS_TABLE.'
+ WHERE status in (\''.implode("','", $status_list).'\')
+;';
+
+ return query2array($query, null, 'user_id');
+}
+
+/**
+ * Delete all derivative files for one or several types
+ *
+ * @param 'all'|int[] $types
+ */
+function clear_derivative_cache($types='all')
+{
+ if ($types === 'all')
+ {
+ $types = ImageStdParams::get_all_types();
+ $types[] = IMG_CUSTOM;
+ }
+ elseif (!is_array($types))
+ {
+ $types = array($types);
+ }
+
+ for ($i=0; $i1)
+ {
+ $pattern .= '(' . implode('|',$types) . ')';
+ }
+ else
+ {
+ $pattern .= $types[0];
+ }
+ $pattern.='\.[a-zA-Z0-9]{3,4}$#';
+
+ if ($contents = @opendir(PHPWG_ROOT_PATH.PWG_DERIVATIVE_DIR))
+ {
+ while (($node = readdir($contents)) !== false)
+ {
+ if ($node != '.'
+ and $node != '..'
+ and is_dir(PHPWG_ROOT_PATH.PWG_DERIVATIVE_DIR.$node))
+ {
+ clear_derivative_cache_rec(PHPWG_ROOT_PATH.PWG_DERIVATIVE_DIR.$node, $pattern);
+ }
+ }
+ closedir($contents);
+ }
+}
+
+/**
+ * Used by clear_derivative_cache()
+ * @ignore
+ */
+function clear_derivative_cache_rec($path, $pattern)
+{
+ $rmdir = true;
+ $rm_index = false;
+
+ if ($contents = opendir($path))
+ {
+ while (($node = readdir($contents)) !== false)
+ {
+ if ($node == '.' or $node == '..')
+ continue;
+ if (is_dir($path.'/'.$node))
+ {
+ $rmdir &= clear_derivative_cache_rec($path.'/'.$node, $pattern);
+ }
+ else
+ {
+ if (preg_match($pattern, $node))
+ {
+ unlink($path.'/'.$node);
+ }
+ elseif ($node=='index.htm')
+ {
+ $rm_index = true;
+ }
+ else
+ {
+ $rmdir = false;
+ }
+ }
+ }
+ closedir($contents);
+
+ if ($rmdir)
+ {
+ if ($rm_index)
+ {
+ unlink($path.'/index.htm');
+ }
+ clearstatcache();
+ @rmdir($path);
+ }
+ return $rmdir;
+ }
+}
+
+/**
+ * Deletes derivatives of a particular element
+ *
+ * @param array $infos ('path'[, 'representative_ext'])
+ * @param 'all'|int $type
+ */
+function delete_element_derivatives($infos, $type='all')
+{
+ $path = $infos['path'];
+ if (!empty($infos['representative_ext']))
+ {
+ $path = original_to_representative( $path, $infos['representative_ext']);
+ }
+ if (substr_compare($path, '../', 0, 3)==0)
+ {
+ $path = substr($path, 3);
+ }
+ $dot = strrpos($path, '.');
+ if ($type=='all')
+ {
+ $pattern = '-*';
+ }
+ else
+ {
+ $pattern = '-'.derivative_to_url($type).'*';
+ }
+ $path = substr_replace($path, $pattern, $dot, 0);
+ if ( ($glob=glob(PHPWG_ROOT_PATH.PWG_DERIVATIVE_DIR.$path)) !== false)
+ {
+ foreach( $glob as $file)
+ {
+ @unlink($file);
+ }
+ }
+}
+
+/**
+ * Returns an array containing sub-directories, excluding ".svn"
+ *
+ * @param string $directory
+ * @return string[]
+ */
+function get_dirs($directory)
+{
+ $sub_dirs = array();
+ if ($opendir = opendir($directory))
+ {
+ while ($file = readdir($opendir))
+ {
+ if ($file != '.'
+ and $file != '..'
+ and is_dir($directory.'/'.$file)
+ and $file != '.svn')
+ {
+ $sub_dirs[] = $file;
+ }
+ }
+ closedir($opendir);
+ }
+ return $sub_dirs;
+}
+
+/**
+ * Recursively delete a directory.
+ *
+ * @param string $path
+ * @param string $trash_path, try to move the directory to this path if it cannot be delete
+ */
+function deltree($path, $trash_path=null)
+{
+ if (is_dir($path))
+ {
+ $fh = opendir($path);
+ while ($file = readdir($fh))
+ {
+ if ($file != '.' and $file != '..')
+ {
+ $pathfile = $path . '/' . $file;
+ if (is_dir($pathfile))
+ {
+ deltree($pathfile, $trash_path);
+ }
+ else
+ {
+ @unlink($pathfile);
+ }
+ }
+ }
+ closedir($fh);
+
+ if (@rmdir($path))
+ {
+ return true;
+ }
+ elseif (!empty($trash_path))
+ {
+ if (!is_dir($trash_path))
+ {
+ @mkgetdir($trash_path, MKGETDIR_RECURSIVE|MKGETDIR_DIE_ON_ERROR|MKGETDIR_PROTECT_HTACCESS);
+ }
+ while ($r = $trash_path . '/' . md5(uniqid(rand(), true)))
+ {
+ if (!is_dir($r))
+ {
+ @rename($path, $r);
+ break;
+ }
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+}
+
+/**
+ * Returns keys to identify the state of main tables. A key consists of the
+ * last modification timestamp and the total of items (separated by a _).
+ * Additionally returns the hash of root path.
+ * Used to invalidate LocalStorage cache on admin pages.
+ *
+ * @param string|string[] list of keys to retrieve (categories,groups,images,tags,users)
+ * @return string[]
+ */
+function get_admin_client_cache_keys($requested=array())
+{
+ $tables = array(
+ 'categories' => CATEGORIES_TABLE,
+ 'groups' => GROUPS_TABLE,
+ 'images' => IMAGES_TABLE,
+ 'tags' => TAGS_TABLE,
+ 'users' => USER_INFOS_TABLE
+ );
+
+ if (!is_array($requested))
+ {
+ $requested = array($requested);
+ }
+ if (empty($requested))
+ {
+ $requested = array_keys($tables);
+ }
+ else
+ {
+ $requested = array_intersect($requested, array_keys($tables));
+ }
+
+ $keys = array(
+ '_hash' => md5(get_absolute_root_url()),
+ );
+
+ foreach ($requested as $item)
+ {
+ $query = '
+SELECT CONCAT(
+ UNIX_TIMESTAMP(MAX(lastmodified)),
+ "_",
+ COUNT(*)
+ )
+ FROM `'. $tables[$item] .'`
+;';
+ list($keys[$item]) = pwg_db_fetch_row(pwg_query($query));
+ }
+
+ return $keys;
+}
+
+/**
+ * Return the list of image ids where md5sum is null
+ *
+ * @return int[] image_ids
+ */
+function get_photos_no_md5sum()
+{
+ $query = '
+SELECT id
+ FROM '.IMAGES_TABLE.'
+ WHERE md5sum is null
+;';
+ return query2array($query, null, 'id');
+}
+
+/**
+ * Compute and add the md5sum of image ids (where md5sum is null)
+ * @param int[] list of image ids and there paths
+ * @return int number of md5sum added
+ */
+function add_md5sum($ids)
+{
+ $query = '
+SELECT
+ id,
+ path
+ FROM '.IMAGES_TABLE.'
+ WHERE id IN ('.implode(', ',$ids).')
+;';
+ $path_for_id = query2array($query, 'id', 'path');
+
+ $updates = array();
+
+ foreach ($path_for_id as $id => $path)
+ {
+ $updates[] = array(
+ 'id' => $id,
+ 'md5sum' => md5_file(PHPWG_ROOT_PATH.$path),
+ );
+ }
+
+ mass_updates(
+ IMAGES_TABLE,
+ array(
+ 'primary' => array('id'),
+ 'update' => array('md5sum')
+ ),
+ $updates
+ );
+
+ return count($path_for_id);
+}
+
+function count_orphans()
+{
+ if (is_null(conf_get_param('count_orphans')))
+ {
+ // we don't care about the list of image_ids, we only care about the number
+ // of orphans, so let's use a faster method than calling count(get_orphans())
+ $query = '
+SELECT
+ COUNT(*)
+ FROM '.IMAGES_TABLE.'
+;';
+ list($image_counter_all) = pwg_db_fetch_row(pwg_query($query));
+
+ $query = '
+SELECT
+ COUNT(DISTINCT(image_id))
+ FROM '.IMAGE_CATEGORY_TABLE.'
+;';
+ list($image_counter_in_categories) = pwg_db_fetch_row(pwg_query($query));
+
+ $counter = $image_counter_all - $image_counter_in_categories;
+ conf_update_param('count_orphans', $counter, true);
+ }
+
+ return conf_get_param('count_orphans');
+}
+
+/**
+ * Return the list of image ids associated to no album
+ *
+ * @return int[] $image_ids
+ */
+function get_orphans()
+{
+ // exclude images in the lounge
+ $query = '
+SELECT
+ image_id
+ FROM '.LOUNGE_TABLE.'
+;';
+ $lounged_ids = query2array($query, null, 'image_id');
+
+ $query = '
+SELECT
+ id
+ FROM '.IMAGES_TABLE.'
+ LEFT JOIN '.IMAGE_CATEGORY_TABLE.' ON id = image_id
+ WHERE category_id is null';
+
+ if (count($lounged_ids) > 0)
+ {
+ $query .= '
+ AND id NOT IN ('.implode(',', $lounged_ids).')';
+ }
+
+ $query.= '
+ ORDER BY id ASC
+;';
+
+ return query2array($query, null, 'id');
+}
+
+/**
+ * save the rank depending on given images order
+ *
+ * The list of ordered images id is supposed to be in the same parent
+ * category
+ *
+ * @param int category_id
+ * @param int[] images
+ * @return void
+ */
+function save_images_order($category_id, $images)
+{
+ $current_rank = 0;
+ $datas = array();
+ foreach ($images as $id)
+ {
+ $datas[] = array(
+ 'category_id' => $category_id,
+ 'image_id' => $id,
+ 'rank' => ++$current_rank,
+ );
+ }
+ $fields = array(
+ 'primary' => array('image_id', 'category_id'),
+ 'update' => array('rank')
+ );
+ mass_updates(IMAGE_CATEGORY_TABLE, $fields, $datas);
+}
+
+/**
+ * Force update on images.lastmodified column. Useful when modifying the tag
+ * list.
+ *
+ * @since 2.9
+ * @param array $image_ids
+ */
+function update_images_lastmodified($image_ids)
+{
+ if (!is_array($image_ids) and is_int($image_ids))
+ {
+ $images_ids = array($image_ids);
+ }
+
+ if (count($image_ids) == 0)
+ {
+ return;
+ }
+
+ $query = '
+UPDATE '.IMAGES_TABLE.'
+ SET lastmodified = NOW()
+ WHERE id IN ('.implode(',', $image_ids).')
+;';
+ pwg_query($query);
+}
+
+/**
+ * Get a more human friendly representation of big numbers. Like 17.8k instead of 17832
+ *
+ * @since 2.9
+ * @param float $numbers
+ */
+function number_format_human_readable($numbers)
+{
+ $readable = array("", "k", "M");
+ $index = 0;
+ $numbers = empty($numbers) ? 0 : $numbers;
+
+ while ($numbers >= 1000)
+ {
+ $numbers /= 1000;
+ $index++;
+
+ if ($index > count($readable) - 1)
+ {
+ $index--;
+ break;
+ }
+ }
+
+ $decimals = 1;
+ if ('' == $readable[$index])
+ {
+ $decimals = 0;
+ }
+
+ return number_format($numbers, $decimals).$readable[$index];
+}
+
+/**
+ * Get infos related to an image
+ *
+ * @since 2.9
+ * @param int $image_id
+ * @param bool $die_on_missing
+ */
+function get_image_infos($image_id, $die_on_missing=false)
+{
+ if (!is_numeric($image_id))
+ {
+ fatal_error('['.__FUNCTION__.'] invalid image identifier '.htmlentities($image_id));
+ }
+
+ $query = '
+SELECT *
+ FROM '.IMAGES_TABLE.'
+ WHERE id = '.$image_id.'
+;';
+ $images = query2array($query);
+ if (count($images) == 0)
+ {
+ if ($die_on_missing)
+ {
+ fatal_error("photo ".$image_id." does not exist");
+ }
+
+ return null;
+ }
+
+ return $images[0];
+}
+
+
+/**
+ * Return each cache image sizes.
+ *
+ * @since 12
+ * @param string $path_to_file
+ */
+function get_cache_size_derivatives($path)
+{
+ $msizes = array(); //final res
+ $subdirs = array(); //sous-rep
+
+ if (is_dir($path))
+ {
+ if ($contents = opendir($path))
+ {
+ while (($node = readdir($contents)) !== false)
+ {
+ if ($node == '.' or $node == '..') continue;
+
+ if (is_file($path.'/'.$node))
+ {
+ if ($split = explode('-' ,$node))
+ {
+ $size_code = substr(end($split), 0, 2);
+ @$msizes[$size_code] += filesize($path.'/'.$node);
+ }
+ }
+ elseif (is_dir($path.'/'.$node))
+ {
+ $tmp_msizes = get_cache_size_derivatives($path.'/'.$node);
+ foreach ($tmp_msizes as $size_key => $value)
+ {
+ @$msizes[$size_key] += $value;
+ }
+ }
+ }
+ }
+ closedir($contents);
+ }
+ return $msizes;
+}
+
+/**
+ * Displays a header warning if we find missing photos on a random sample.
+ *
+ * @since 13.4.0
+ */
+function fs_quick_check()
+{
+ global $page, $conf;
+
+ if ($conf['fs_quick_check_period'] == 0)
+ {
+ return;
+ }
+
+ if (isset($page[__FUNCTION__.'_already_called']))
+ {
+ return;
+ }
+
+ $page[__FUNCTION__.'_already_called'] = true;
+ conf_update_param('fs_quick_check_last_check', date('c'));
+
+ $query = '
+SELECT
+ id
+ FROM '.IMAGES_TABLE.'
+ WHERE date_available < \'2022-12-08 00:00:00\'
+ AND path LIKE \'./upload/%\'
+ LIMIT 5000
+;';
+ $issue1827_ids = query2array($query, null, 'id');
+ shuffle($issue1827_ids);
+ $issue1827_ids = array_slice($issue1827_ids, 0, 50);
+
+ $query = '
+SELECT
+ id
+ FROM '.IMAGES_TABLE.'
+ LIMIT 5000
+;';
+ $random_image_ids = query2array($query, null, 'id');
+ shuffle($random_image_ids);
+ $random_image_ids = array_slice($random_image_ids, 0, 50);
+
+ $fs_quick_check_ids = array_unique(array_merge($issue1827_ids, $random_image_ids));
+
+ if (count($fs_quick_check_ids) < 1)
+ {
+ return;
+ }
+
+ $query = '
+SELECT
+ id,
+ path
+ FROM '.IMAGES_TABLE.'
+ WHERE id IN ('.implode(',', $fs_quick_check_ids).')
+;';
+ $fsqc_paths = query2array($query, 'id', 'path');
+
+ foreach ($fsqc_paths as $id => $path)
+ {
+ if (!file_exists($path))
+ {
+ global $template;
+
+ $template->assign(
+ 'header_msgs',
+ array(
+ l10n('Some photos are missing from your file system. Details provided by plugin Check Uploads'),
+ )
+ );
+
+ return;
+ }
+ }
+
+ // search for duplicate paths
+ $query = '
+SELECT
+ path
+ FROM '.IMAGES_TABLE.'
+ GROUP BY path
+ HAVING COUNT(*) > 1
+;';
+ $duplicate_paths = query2array($query);
+
+ if (count($duplicate_paths) > 0)
+ {
+ global $template;
+
+ $template->assign(
+ 'header_msgs',
+ array(
+ l10n('We have found %d duplicate paths. Details provided by plugin Check Uploads', count($duplicate_paths)),
+ )
+ );
+
+ return;
+ }
+}
+
+/**
+ * Return latest news from piwigo.org.
+ *
+ * @since 13
+ */
+function get_piwigo_news()
+{
+ global $lang_info;
+
+ $news = null;
+
+ $cache_path = PHPWG_ROOT_PATH.conf_get_param('data_location').'cache/piwigo_latest_news-'.$lang_info['code'].'.cache.php';
+ if (!is_file($cache_path) or filemtime($cache_path) < strtotime('24 hours ago'))
+ {
+ $url = PHPWG_URL.'/ws.php?method=porg.news.getLatest&format=json';
+
+ if (fetchRemote($url, $content))
+ {
+ $all_news = array();
+
+ $porg_news_getLatest = json_decode($content, true);
+
+ if (isset($porg_news_getLatest['result']))
+ {
+ $topic = $porg_news_getLatest['result'];
+
+ $news = array(
+ 'id' => $topic['topic_id'],
+ 'subject' => $topic['subject'],
+ 'posted_on' => $topic['posted_on'],
+ 'posted' => format_date($topic['posted_on']),
+ 'url' => $topic['url'],
+ );
+ }
+
+ if (mkgetdir(dirname($cache_path)))
+ {
+ file_put_contents($cache_path, serialize($news));
+ }
+ }
+ else
+ {
+ return array();
+ }
+ }
+
+ if (is_null($news))
+ {
+ $news = unserialize(file_get_contents($cache_path));
+ }
+
+ return $news;
+}
+
+function get_graphics_library()
+{
+ global $conf;
+
+ include_once(PHPWG_ROOT_PATH.'admin/include/image.class.php');
+
+ $library = pwg_image::get_library();
+
+ switch (pwg_image::get_library())
+ {
+ case 'ext_imagick':
+ exec($conf['ext_imagick_dir'].pwg_image::get_ext_imagick_command().' -version', $returnarray);
+ if (preg_match('/Version: ImageMagick (\d+\.\d+\.\d+-?\d*)/', $returnarray[0], $match))
+ {
+ $library.= '/'.$match[1];
+ }
+ break;
+
+ case 'imagick':
+ $img = new Imagick();
+ $version = $img->getVersion();
+ if (preg_match('/ImageMagick \d+\.\d+\.\d+-?\d*/', $version['versionString'], $match))
+ {
+ $library.= '/'.$match[0];
+ }
+ break;
+
+ case 'gd':
+ $gd_info = gd_info();
+ $library.= '/'.@$gd_info['GD Version'];
+ break;
+ }
+
+ return $library;
+}
+
+function get_graphics_library_label()
+{
+ list($library_code, $library_version) = explode('/', get_graphics_library());
+
+ $label_for_lib = array(
+ 'imagick' => 'ImageMagick',
+ 'ext_imagick' => 'External ImageMagick',
+ 'gd' => 'GD',
+ );
+
+ return $label_for_lib[$library_code].' '.$library_version;
+}
+
+function get_pwg_general_statitics()
+{
+ $stats = array();
+
+ $query = '
+SELECT COUNT(*)
+ FROM '.IMAGES_TABLE.'
+;';
+ list($stats['nb_photos']) = pwg_db_fetch_row(pwg_query($query));
+
+ $query = '
+SELECT COUNT(*)
+ FROM '.CATEGORIES_TABLE.'
+;';
+ list($stats['nb_categories']) = pwg_db_fetch_row(pwg_query($query));
+
+ $query = '
+SELECT COUNT(*)
+ FROM '.TAGS_TABLE.'
+;';
+ list($stats['nb_tags']) = pwg_db_fetch_row(pwg_query($query));
+
+ $query = '
+SELECT COUNT(*)
+ FROM '.IMAGE_TAG_TABLE.'
+;';
+ list($stats['nb_image_tag']) = pwg_db_fetch_row(pwg_query($query));
+
+ $query = '
+SELECT COUNT(*)
+ FROM '.USERS_TABLE.'
+;';
+ list($stats['nb_users']) = pwg_db_fetch_row(pwg_query($query));
+
+ $query = '
+SELECT
+ COUNT(*)
+ FROM '.USER_INFOS_TABLE.'
+ WHERE status IN (\'webmaster\', \'admin\')
+;';
+ list($stats['nb_admins']) = pwg_db_fetch_row(pwg_query($query));
+
+ $query = '
+SELECT COUNT(*)
+ FROM `'.GROUPS_TABLE.'`
+;';
+ list($stats['nb_groups']) = pwg_db_fetch_row(pwg_query($query));
+
+ $query = '
+SELECT COUNT(*)
+ FROM '.RATE_TABLE.'
+;';
+ list($stats['nb_rates']) = pwg_db_fetch_row(pwg_query($query));
+
+ $query = '
+SELECT
+ SUM(nb_pages)
+ FROM '.HISTORY_SUMMARY_TABLE.'
+ WHERE month IS NULL
+;';
+ list($stats['nb_views']) = pwg_db_fetch_row(pwg_query($query));
+
+ $query = '
+SELECT
+ SUM(filesize)
+ FROM '.IMAGES_TABLE.'
+;';
+ list($stats['disk_usage']) = pwg_db_fetch_row(pwg_query($query));
+
+ $query = '
+SELECT
+ COUNT(*),
+ SUM(filesize)
+ FROM '.IMAGE_FORMAT_TABLE.'
+;';
+ list($stats['nb_formats'], $stats['formats_disk_usage']) = pwg_db_fetch_row(pwg_query($query));
+
+ $stats['disk_usage'] += $stats['formats_disk_usage'];
+
+ return $stats;
+}
+
+function get_installation_date()
+{
+ $candidate = null;
+
+ // Piwigo first beta versions were created in septembre 2001, so it's not possible
+ // to have an installation prior to this "origin of times"
+ $piwigo_origins = '2001-09-01 00:00:00';
+
+ $query = '
+SELECT
+ registration_date
+ FROM '.USER_INFOS_TABLE.'
+ WHERE user_id = 2
+;';
+ $users = query2array($query);
+ if (count($users) > 0)
+ {
+ $candidate = $users[0]['registration_date'];
+ }
+
+ if (empty($candidate) or strtotime($candidate) < strtotime($piwigo_origins))
+ {
+ $query = '
+SELECT
+ MIN(registration_date) AS min_registration_date
+ FROM '.USER_INFOS_TABLE.'
+ WHERE registration_date > \''.$piwigo_origins.'\'
+;';
+ $users = query2array($query);
+ if (count($users) > 0)
+ {
+ $candidate = $users[0]['min_registration_date'];
+ }
+ }
+
+ if (empty($candidate) or strtotime($candidate) < strtotime($piwigo_origins))
+ {
+ // let's find another candidate
+ $query = '
+SELECT
+ date_available
+ FROM '.IMAGES_TABLE.'
+ ORDER BY id ASC
+ LIMIT 1
+;';
+ $images = query2array($query);
+ if (count($images) > 0)
+ {
+ $candidate = $images[0]['date_available'];
+ }
+ }
+
+ return $candidate;
+}
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/include/functions_history.inc.php b/Piwingo/piwigo-data/piwigo/admin/include/functions_history.inc.php
new file mode 100644
index 0000000..5ea27fa
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/include/functions_history.inc.php
@@ -0,0 +1,506 @@
+set_id('history');
+ $tabsheet->select($page['page']);
+ $tabsheet->assign();
+}
+
+/**
+ * Callback used to sort history entries
+ */
+function history_compare($a, $b)
+{
+ return strcmp($a['date'].$a['time'], $b['date'].$b['time']);
+}
+
+/**
+ * Perform history search.
+ *
+ * @param array $data - used in trigger_change
+ * @param array $search
+ * @param string[] $types
+ * @param array
+ */
+function get_history($data, $search, $types)
+{
+ if (isset($search['fields']['filename']))
+ {
+ $query = '
+SELECT
+ id
+ FROM '.IMAGES_TABLE.'
+ WHERE file LIKE \''.$search['fields']['filename'].'\'
+;';
+ $search['image_ids'] = array_from_query($query, 'id');
+ }
+
+ // echo ''; print_r($search); echo '
';
+
+ $clauses = array();
+
+ if (isset($search['fields']['date-after']))
+ {
+ $clauses[] = "date >= '".$search['fields']['date-after']."'";
+ }
+
+ if (isset($search['fields']['date-before']))
+ {
+ $clauses[] = "date <= '".$search['fields']['date-before']."'";
+ }
+
+ if (isset($search['fields']['types']))
+ {
+ $local_clauses = array();
+
+ foreach ($types as $type) {
+ if (in_array($type, $search['fields']['types'])) {
+ $clause = 'image_type ';
+ if ($type == 'none')
+ {
+ $clause.= 'IS NULL';
+ }
+ else
+ {
+ $clause.= "= '".$type."'";
+ }
+
+ $local_clauses[] = $clause;
+ }
+ }
+
+ if (count($local_clauses) > 0)
+ {
+ $clauses[] = implode(' OR ', $local_clauses);
+ }
+ }
+
+ if (isset($search['fields']['user'])
+ and $search['fields']['user'] != -1)
+ {
+ $clauses[] = 'user_id = '.$search['fields']['user'];
+ }
+
+ if (isset($search['fields']['image_id']))
+ {
+ $clauses[] = 'image_id = '.$search['fields']['image_id'];
+ }
+
+ if (isset($search['fields']['filename']))
+ {
+ if (count($search['image_ids']) == 0)
+ {
+ // a clause that is always false
+ $clauses[] = '1 = 2 ';
+ }
+ else
+ {
+ $clauses[] = 'image_id IN ('.implode(', ', $search['image_ids']).')';
+ }
+ }
+
+ if (isset($search['fields']['ip']))
+ {
+ $clauses[] = 'IP LIKE "'.$search['fields']['ip'].'"';
+ }
+
+ $clauses = prepend_append_array_items($clauses, '(', ')');
+
+ $where_separator =
+ implode(
+ "\n AND ",
+ $clauses
+ );
+
+ $query = '
+SELECT
+ date,
+ time,
+ user_id,
+ IP,
+ section,
+ category_id,
+ search_id,
+ tag_ids,
+ image_id,
+ image_type
+ FROM '.HISTORY_TABLE.'
+ WHERE '.$where_separator.'
+;';
+
+ // LIMIT '.$conf['nb_logs_page'].' OFFSET '.$page['start'].'
+
+ $result = pwg_query($query);
+
+ while ($row = pwg_db_fetch_assoc($result))
+ {
+ $data[] = $row;
+ }
+
+ return $data;
+}
+
+/**
+ * Compute statistics from history table to history_summary table
+ *
+ * @param int $max_lines - to only compute the next X lines, not the whole remaining lines
+ */
+function history_summarize($max_lines=null)
+{
+ // we need to know which was the last line "summarized"
+ $query = '
+SELECT
+ *
+ FROM '.HISTORY_SUMMARY_TABLE.'
+ WHERE history_id_to IS NOT NULL
+ ORDER BY history_id_to DESC
+ LIMIT 1
+;';
+ $summary_lines = query2array($query);
+
+ $history_min_id = 0;
+ if (count($summary_lines) > 0)
+ {
+ $last_summary = $summary_lines[0];
+ $history_min_id = $last_summary['history_id_to'];
+ }
+ else
+ {
+ // if we have no "reference", ie "starting point", we need to find
+ // one. And "0" is not the right answer here, because history table may
+ // have been purged already.
+ $query = '
+SELECT
+ MIN(id) AS min_id
+ FROM '.HISTORY_TABLE.'
+;';
+ $history_lines = query2array($query);
+ if (count($history_lines) > 0)
+ {
+ $history_min_id = $history_lines[0]['min_id'] - 1;
+ }
+ }
+
+ $query = '
+SELECT
+ date,
+ '.pwg_db_get_hour('time').' AS hour,
+ MIN(id) AS min_id,
+ MAX(id) AS max_id,
+ COUNT(*) AS nb_pages
+ FROM '.HISTORY_TABLE.'
+ WHERE id > '.$history_min_id;
+
+ if (isset($max_lines))
+ {
+ $query.= '
+ AND id <= '.($history_min_id + $max_lines);
+ }
+
+ $query.= '
+ GROUP BY
+ date,
+ hour
+ ORDER BY
+ date ASC,
+ hour ASC
+;';
+ $result = pwg_query($query);
+
+ $need_update = array();
+
+ $is_first = true;
+ $first_time_key = null;
+
+ while ($row = pwg_db_fetch_assoc($result))
+ {
+ $time_keys = array(
+ substr($row['date'], 0, 4), //yyyy
+ substr($row['date'], 0, 7), //yyyy-mm
+ substr($row['date'], 0, 10),//yyyy-mm-dd
+ sprintf(
+ '%s-%02u',
+ $row['date'], $row['hour']
+ ),
+ );
+
+ foreach ($time_keys as $time_key)
+ {
+ if (!isset($need_update[$time_key]))
+ {
+ $need_update[$time_key] = array(
+ 'nb_pages' => 0,
+ 'history_id_from' => $row['min_id'],
+ 'history_id_to' => $row['max_id'],
+ );
+ }
+ $need_update[$time_key]['nb_pages'] += $row['nb_pages'];
+
+ if ($row['min_id'] < $need_update[$time_key]['history_id_from'])
+ {
+ $need_update[$time_key]['history_id_from'] = $row['min_id'];
+ }
+
+ if ($row['max_id'] > $need_update[$time_key]['history_id_to'])
+ {
+ $need_update[$time_key]['history_id_to'] = $row['max_id'];
+ }
+ }
+
+ if ($is_first)
+ {
+ $is_first = false;
+ $first_time_key = $time_keys[3];
+ }
+ }
+
+// Only the oldest time_key might be already summarized, so we have to
+// update the 4 corresponding lines instead of simply inserting them.
+//
+// For example, if the oldest unsummarized is 2005.08.25.21, the 4 lines
+// that can be updated are:
+//
+// +---------------+----------+
+// | id | nb_pages |
+// +---------------+----------+
+// | 2005 | 241109 |
+// | 2005-08 | 20133 |
+// | 2005-08-25 | 620 |
+// | 2005-08-25-21 | 151 |
+// +---------------+----------+
+
+ $updates = array();
+ $inserts = array();
+
+ if (isset($first_time_key))
+ {
+ list($year, $month, $day, $hour) = explode('-', $first_time_key);
+
+ $query = '
+SELECT *
+ FROM '.HISTORY_SUMMARY_TABLE.'
+ WHERE year='.$year.'
+ AND ( month IS NULL
+ OR ( month='.$month.'
+ AND ( day is NULL
+ OR (day='.$day.'
+ AND (hour IS NULL OR hour='.$hour.')
+ )
+ )
+ )
+ )
+;';
+ $result = pwg_query($query);
+ while ($row = pwg_db_fetch_assoc($result))
+ {
+ $key = sprintf('%4u', $row['year']);
+ if ( isset($row['month']) )
+ {
+ $key .= sprintf('-%02u', $row['month']);
+ if ( isset($row['day']) )
+ {
+ $key .= sprintf('-%02u', $row['day']);
+ if ( isset($row['hour']) )
+ {
+ $key .= sprintf('-%02u', $row['hour']);
+ }
+ }
+ }
+
+ if (isset($need_update[$key]))
+ {
+ $row['nb_pages'] += $need_update[$key]['nb_pages'];
+ $row['history_id_to'] = $need_update[$key]['history_id_to'];
+ $updates[] = $row;
+ unset($need_update[$key]);
+ }
+ }
+ }
+
+ foreach ($need_update as $time_key => $summary)
+ {
+ $time_tokens = explode('-', $time_key);
+
+ $inserts[] = array(
+ 'year' => $time_tokens[0],
+ 'month' => @$time_tokens[1],
+ 'day' => @$time_tokens[2],
+ 'hour' => @$time_tokens[3],
+ 'nb_pages' => $summary['nb_pages'],
+ 'history_id_from' => $summary['history_id_from'],
+ 'history_id_to' => $summary['history_id_to'],
+ );
+ }
+
+ if (count($updates) > 0)
+ {
+ mass_updates(
+ HISTORY_SUMMARY_TABLE,
+ array(
+ 'primary' => array('year','month','day','hour'),
+ 'update' => array('nb_pages','history_id_to'),
+ ),
+ $updates
+ );
+ }
+
+ if (count($inserts) > 0)
+ {
+ mass_inserts(
+ HISTORY_SUMMARY_TABLE,
+ array_keys($inserts[0]),
+ $inserts
+ );
+ }
+}
+
+/**
+ * Smart purge on history table. Keep some lines, purge only summarized lines
+ *
+ * @since 2.9
+ */
+function history_autopurge()
+{
+ global $conf, $logger;
+
+ if (0 == $conf['history_autopurge_keep_lines'])
+ {
+ return;
+ }
+
+ // we want to purge only if there are too many lines and if the lines are summarized
+
+ $query = '
+SELECT
+ COUNT(*)
+ FROM '.HISTORY_TABLE.'
+;';
+ list($count) = pwg_db_fetch_row(pwg_query($query));
+
+ if ($count <= $conf['history_autopurge_keep_lines'])
+ {
+ history_remove_summarized_column();
+ return; // no need to purge for now
+ }
+
+ // 1) find the last summarized history line
+ $query = '
+SELECT
+ *
+ FROM '.HISTORY_SUMMARY_TABLE.'
+ WHERE history_id_to IS NOT NULL
+ ORDER BY history_id_to DESC
+ LIMIT 1
+;';
+ $summary_lines = query2array($query);
+ if (count($summary_lines) == 0)
+ {
+ return; // lines not summarized, no purge
+ }
+
+ $history_id_last_summarized = $summary_lines[0]['history_id_to'];
+
+ // 2) find the latest history line (and substract the number of lines to keep)
+ $query = '
+SELECT
+ id
+ FROM '.HISTORY_TABLE.'
+ ORDER BY id DESC
+ LIMIT 1
+;';
+ $history_lines = query2array($query);
+ if (count($history_lines) == 0)
+ {
+ return;
+ }
+
+ $history_id_latest = $history_lines[0]['id'];
+
+ // 3) find the oldest history line (and add the number of lines to delete)
+ $query = '
+SELECT
+ id
+ FROM '.HISTORY_TABLE.'
+ ORDER BY id ASC
+ LIMIT 1
+;';
+ $history_lines = query2array($query);
+ $history_id_oldest = $history_lines[0]['id'];
+
+ $search_min = array(
+ $history_id_last_summarized,
+ $history_id_latest - $conf['history_autopurge_keep_lines'],
+ $history_id_oldest + $conf['history_autopurge_blocksize'],
+ );
+
+ $history_id_delete_before = min($search_min);
+
+ $logger->debug(__FUNCTION__.', '.join('/', $search_min));
+
+ $query = '
+DELETE
+ FROM '.HISTORY_TABLE.'
+ WHERE id < '.$history_id_delete_before.'
+;';
+ pwg_query($query);
+
+ history_remove_summarized_column();
+}
+
+function history_remove_summarized_column()
+{
+ global $conf;
+
+ if (isset($conf['history_summarized_dropped']) and $conf['history_summarized_dropped'])
+ {
+ return;
+ }
+
+ $query = '
+SELECT
+ COUNT(*)
+ FROM '.HISTORY_TABLE.'
+;';
+ list($count) = pwg_db_fetch_row(pwg_query($query));
+
+ if ($count > $conf['history_autopurge_keep_lines']+$conf['history_autopurge_blocksize'])
+ {
+ // it's not yet time to remove history.summarized
+ return;
+ }
+
+ $result = pwg_query('SHOW COLUMNS FROM `'.HISTORY_TABLE.'` LIKE "summarized";');
+ if (pwg_db_num_rows($result))
+ {
+ pwg_query('ALTER TABLE `'.HISTORY_TABLE.'` DROP COLUMN `summarized`;');
+ }
+
+ conf_update_param('history_summarized_dropped', true);
+}
+
+add_event_handler('get_history', 'get_history');
+trigger_notify('functions_history_included');
+
+?>
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/include/functions_install.inc.php b/Piwingo/piwigo-data/piwigo/admin/include/functions_install.inc.php
new file mode 100644
index 0000000..3a3aeb1
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/include/functions_install.inc.php
@@ -0,0 +1,113 @@
+fs_themes as $theme_id => $fs_theme)
+ {
+ if (in_array($theme_id, array('modus')))
+ {
+ $themes->perform_action('activate', $theme_id);
+ }
+ }
+}
+
+/**
+ * Automatically activate some core plugins
+ */
+function activate_core_plugins()
+{
+ include_once(PHPWG_ROOT_PATH.'admin/include/plugins.class.php');
+
+ $plugins = new plugins();
+
+ foreach($plugins->fs_plugins as $plugin_id => $fs_plugin)
+ {
+ if (in_array($plugin_id, array()))
+ {
+ $plugins->perform_action('activate', $plugin_id);
+ }
+ }
+}
+
+/**
+ * Connect to database during installation. Uses $_POST.
+ *
+ * @param array &$infos - populated with infos
+ * @param array &$errors - populated with errors
+ */
+function install_db_connect(&$infos, &$errors)
+{
+ try
+ {
+ pwg_db_connect($_POST['dbhost'], $_POST['dbuser'],
+ $_POST['dbpasswd'], $_POST['dbname']);
+ pwg_db_check_version();
+ }
+ catch (Exception $e)
+ {
+ $errors[] = l10n($e->getMessage());
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/include/functions_metadata.php b/Piwingo/piwigo-data/piwigo/admin/include/functions_metadata.php
new file mode 100644
index 0000000..3c8c082
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/include/functions_metadata.php
@@ -0,0 +1,437 @@
+ $value)
+ {
+ if (in_array($pwg_key, array('date_creation', 'date_available')))
+ {
+ if (preg_match('/(\d{4})(\d{2})(\d{2})/', $value, $matches))
+ {
+ $year = $matches[1];
+ $month = $matches[2];
+ $day = $matches[3];
+
+ if (!checkdate($month, $day, $year))
+ {
+ // we suppose the year is correct
+ $month = 1;
+ $day = 1;
+ }
+
+ $iptc[$pwg_key] = $year.'-'.$month.'-'.$day;
+ }
+ }
+ }
+
+ if (isset($iptc['keywords']))
+ {
+ $iptc['keywords'] = metadata_normalize_keywords_string($iptc['keywords']);
+ }
+
+ foreach ($iptc as $pwg_key => $value)
+ {
+ $iptc[$pwg_key] = addslashes($iptc[$pwg_key]);
+ }
+
+ return $iptc;
+}
+
+/**
+ * Returns EXIF metadata to sync from a file, depending on EXIF mapping.
+ *
+ * @param string $file
+ * @return array
+ */
+function get_sync_exif_data($file)
+{
+ global $conf;
+
+ $exif = get_exif_data($file, $conf['use_exif_mapping']);
+
+ foreach ($exif as $pwg_key => $value)
+ {
+ if (in_array($pwg_key, array('date_creation', 'date_available')))
+ {
+ if (preg_match('/^(\d{4}).(\d{2}).(\d{2}) (\d{2}).(\d{2}).(\d{2})/', $value, $matches))
+ {
+ $exif[$pwg_key] = $matches[1].'-'.$matches[2].'-'.$matches[3].' '.$matches[4].':'.$matches[5].':'.$matches[6];
+ if ($exif[$pwg_key] == '0000-00-00 00:00:00')
+ {
+ $exif[$pwg_key] = Null;
+ }
+ }
+ elseif (preg_match('/^(\d{4}).(\d{2}).(\d{2})/', $value, $matches))
+ {
+ $exif[$pwg_key] = $matches[1].'-'.$matches[2].'-'.$matches[3];
+ }
+ else
+ {
+ unset($exif[$pwg_key]);
+ continue;
+ }
+ }
+
+ if (in_array($pwg_key, array('keywords', 'tags')))
+ {
+ $exif[$pwg_key] = metadata_normalize_keywords_string($exif[$pwg_key]);
+ }
+
+ if (empty($exif[$pwg_key]))
+ {
+ unset($exif[$pwg_key]);
+ continue;
+ }
+
+ $exif[$pwg_key] = addslashes($exif[$pwg_key]);
+ }
+
+ return $exif;
+}
+
+/**
+ * Get all potential file metadata fields, including IPTC and EXIF.
+ *
+ * @return string[]
+ */
+function get_sync_metadata_attributes()
+{
+ global $conf;
+
+ $update_fields = array('filesize', 'width', 'height');
+
+ if ($conf['use_exif'])
+ {
+ $update_fields =
+ array_merge(
+ $update_fields,
+ array_keys($conf['use_exif_mapping']),
+ array('latitude', 'longitude')
+ );
+ }
+
+ if ($conf['use_iptc'])
+ {
+ $update_fields =
+ array_merge(
+ $update_fields,
+ array_keys($conf['use_iptc_mapping'])
+ );
+ }
+
+ return array_unique($update_fields);
+}
+
+/**
+ * Get all metadata of a file.
+ *
+ * @param array $infos - (path[, representative_ext])
+ * @return array - includes data provided in $infos
+ */
+function get_sync_metadata($infos)
+{
+ global $conf;
+ $file = PHPWG_ROOT_PATH.$infos['path'];
+ $fs = @filesize($file);
+
+ if ($fs===false)
+ {
+ return false;
+ }
+
+ $infos['filesize'] = floor($fs/1024);
+
+ $is_tiff = false;
+
+ if (isset($infos['representative_ext']))
+ {
+ if ($image_size = @getimagesize($file))
+ {
+ $type = $image_size[2];
+
+ if (IMAGETYPE_TIFF_MM == $type or IMAGETYPE_TIFF_II == $type)
+ {
+ // in case of TIFF files, we want to use the original file and not
+ // the representative for EXIF/IPTC, but we need the representative
+ // for width/height (to compute the multiple size dimensions)
+ $is_tiff = true;
+ }
+ }
+
+ $file = original_to_representative($file, $infos['representative_ext']);
+ }
+
+ if (function_exists('mime_content_type'))
+ {
+ $mime_type = mime_content_type($file);
+
+ if (str_starts_with($mime_type, 'image/'))
+ {
+ if (in_array($mime_type, array('image/svg+xml', 'image/svg')))
+ {
+ $xml = file_get_contents($file);
+
+ $xmlget = simplexml_load_string($xml);
+ $xmlattributes = $xmlget->attributes();
+ $width = $xmlattributes->width;
+ $height = $xmlattributes->height;
+ $vb = (string) $xmlattributes->viewBox;
+
+ if (isset($width) and $width != "")
+ {
+ $infos['width'] = (int) $width;
+ } elseif (isset($vb))
+ {
+ $infos['width'] = round(explode(" ", $vb)[2]);
+ }
+
+ if (isset($height) and $height != "")
+ {
+ $infos['height'] = (int) $height;
+ } elseif (isset($vb))
+ {
+ $infos['height'] = round(explode(" ", $vb)[3]);
+ }
+ }
+ if ($image_size = @getimagesize($file))
+ {
+ $infos['width'] = $image_size[0];
+ $infos['height'] = $image_size[1];
+ }
+ }
+ }
+
+ if ($is_tiff)
+ {
+ // back to original file
+ $file = PHPWG_ROOT_PATH.$infos['path'];
+ }
+
+ if ($conf['use_exif'])
+ {
+ $exif = get_sync_exif_data($file);
+ $infos = array_merge($infos, $exif);
+ }
+
+ if ($conf['use_iptc'])
+ {
+ $iptc = get_sync_iptc_data($file);
+ $infos = array_merge($infos, $iptc);
+ }
+
+ foreach (array('name', 'author') as $single_line_field)
+ {
+ if (isset($infos[$single_line_field]))
+ {
+ foreach (array("\r\n", "\n", "\r") as $to_replace_string)
+ {
+ $infos[$single_line_field] = str_replace($to_replace_string, ' ', $infos[$single_line_field]);
+ }
+ }
+ }
+
+ return $infos;
+}
+
+/**
+ * Sync all metadata of a list of images.
+ * Metadata are fetched from original files and saved in database.
+ *
+ * @param int[] $ids
+ */
+function sync_metadata($ids)
+{
+ global $conf;
+
+ if (!defined('CURRENT_DATE'))
+ {
+ define('CURRENT_DATE', date('Y-m-d'));
+ }
+
+ $datas = array();
+ $tags_of = array();
+
+ $query = '
+SELECT id, path, representative_ext
+ FROM '.IMAGES_TABLE.'
+ WHERE id IN (
+'.wordwrap(implode(', ', $ids), 160, "\n").'
+)
+;';
+
+ $result = pwg_query($query);
+ while ($data = pwg_db_fetch_assoc($result))
+ {
+ $data = get_sync_metadata($data);
+ if ($data === false)
+ {
+ continue;
+ }
+ // print_r($data);
+ $id = $data['id'];
+ foreach (array('keywords', 'tags') as $key)
+ {
+ if (isset($data[$key]))
+ {
+ if (!isset($tags_of[$id]))
+ {
+ $tags_of[$id] = array();
+ }
+
+ foreach (explode(',', $data[$key]) as $tag_name)
+ {
+ $tags_of[$id][] = tag_id_from_tag_name($tag_name);
+ }
+ }
+ }
+
+ $data['date_metadata_update'] = CURRENT_DATE;
+
+ $datas[] = $data;
+ }
+
+ if (count($datas) > 0)
+ {
+ $update_fields = get_sync_metadata_attributes();
+ $update_fields[] = 'date_metadata_update';
+
+ $update_fields = array_diff(
+ $update_fields,
+ array('tags', 'keywords')
+ );
+
+ mass_updates(
+ IMAGES_TABLE,
+ array(
+ 'primary' => array('id'),
+ 'update' => $update_fields
+ ),
+ $datas,
+ MASS_UPDATES_SKIP_EMPTY
+ );
+ }
+
+ set_tags_of($tags_of);
+}
+
+/**
+ * Returns an array associating element id (images.id) with its complete
+ * path in the filesystem
+ *
+ * @param int $category_id
+ * @param int $site_id
+ * @param boolean $recursive
+ * @param boolean $only_new
+ * @return array
+ */
+function get_filelist($category_id = '', $site_id=1, $recursive = false,
+ $only_new = false)
+{
+ // filling $cat_ids : all categories required
+ $cat_ids = array();
+
+ $query = '
+SELECT id
+ FROM '.CATEGORIES_TABLE.'
+ WHERE site_id = '.$site_id.'
+ AND dir IS NOT NULL';
+ if (is_numeric($category_id))
+ {
+ if ($recursive)
+ {
+ $query.= '
+ AND uppercats '.DB_REGEX_OPERATOR.' \'(^|,)'.$category_id.'(,|$)\'
+';
+ }
+ else
+ {
+ $query.= '
+ AND id = '.$category_id.'
+';
+ }
+ }
+ $query.= '
+;';
+ $result = pwg_query($query);
+ while ($row = pwg_db_fetch_assoc($result))
+ {
+ $cat_ids[] = $row['id'];
+ }
+
+ if (count($cat_ids) == 0)
+ {
+ return array();
+ }
+
+ $query = '
+SELECT id, path, representative_ext
+ FROM '.IMAGES_TABLE.'
+ WHERE storage_category_id IN ('.implode(',', $cat_ids).')';
+ if ($only_new)
+ {
+ $query.= '
+ AND date_metadata_update IS NULL
+';
+ }
+ $query.= '
+;';
+ return hash_from_query($query, 'id');
+}
+
+/**
+ * Returns the list of keywords (future tags) correctly separated with
+ * commas. Other separators are converted into commas.
+ *
+ * @param string $keywords_string
+ * @return string
+ */
+function metadata_normalize_keywords_string($keywords_string)
+{
+ global $conf;
+
+ $keywords_string = preg_replace($conf['metadata_keyword_separator_regex'], ',', $keywords_string);
+ // new lines are always considered as keyword separators
+ $keywords_string = str_replace(array("\r\n", "\n", "\r"), ',', $keywords_string);
+ $keywords_string = preg_replace('/,+/', ',', $keywords_string);
+ $keywords_string = preg_replace('/^,+|,+$/', '', $keywords_string);
+
+ $keywords_string = implode(
+ ',',
+ array_unique(
+ explode(
+ ',',
+ $keywords_string
+ )
+ )
+ );
+
+ return $keywords_string;
+}
+?>
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/include/functions_notification_by_mail.inc.php b/Piwingo/piwigo-data/piwigo/admin/include/functions_notification_by_mail.inc.php
new file mode 100644
index 0000000..e9b50f5
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/include/functions_notification_by_mail.inc.php
@@ -0,0 +1,531 @@
+ get_moment(),
+ 'sendmail_timeout' => (intval(ini_get('max_execution_time')) * $conf['nbm_max_treatment_timeout_percent']),
+ 'is_sendmail_timeout' => false
+ );
+
+if
+ (
+ (!isset($env_nbm['sendmail_timeout'])) or
+ (!is_numeric($env_nbm['sendmail_timeout'])) or
+ ($env_nbm['sendmail_timeout'] <= 0)
+ )
+{
+ $env_nbm['sendmail_timeout'] = $conf['nbm_treatment_timeout_default'];
+}
+
+/*
+ * Search an available check_key
+ *
+ * It's a copy of function find_available_feed_id
+ *
+ * @return string nbm identifier
+ */
+function find_available_check_key()
+{
+ while (true)
+ {
+ $key = generate_key(16);
+ $query = '
+select
+ count(*)
+from
+ '.USER_MAIL_NOTIFICATION_TABLE.'
+where
+ check_key = \''.$key.'\';';
+
+ list($count) = pwg_db_fetch_row(pwg_query($query));
+ if ($count == 0)
+ {
+ return $key;
+ }
+ }
+}
+
+/*
+ * Check sendmail timeout state
+ *
+ * @return true, if it's timeout
+ */
+function check_sendmail_timeout()
+{
+ global $env_nbm;
+
+ $env_nbm['is_sendmail_timeout'] = ((get_moment() - $env_nbm['start_time']) > $env_nbm['sendmail_timeout']);
+
+ return $env_nbm['is_sendmail_timeout'];
+}
+
+
+/*
+ * Add quote to all elements of check_key_list
+ *
+ * @return quoted check key list
+ */
+function quote_check_key_list($check_key_list = array())
+{
+ return array_map(function($s) { return '\''.$s.'\''; } , $check_key_list);
+}
+
+/*
+ * Execute all main queries to get list of user
+ *
+ * Type are the type of list 'subscribe', 'send'
+ *
+ * return array of users
+ */
+function get_user_notifications($action, $check_key_list = array(), $enabled_filter_value = '')
+{
+ global $conf;
+
+ $data_users = array();
+
+ if (in_array($action, array('subscribe', 'send')))
+ {
+ $quoted_check_key_list = quote_check_key_list($check_key_list);
+ if (count($quoted_check_key_list) != 0 )
+ {
+ $query_and_check_key = ' and
+ check_key in ('.implode(",", $quoted_check_key_list).') ';
+ }
+ else
+ {
+ $query_and_check_key = '';
+ }
+
+ $query = '
+select
+ N.user_id,
+ N.check_key,
+ U.'.$conf['user_fields']['username'].' as username,
+ U.'.$conf['user_fields']['email'].' as mail_address,
+ N.enabled,
+ N.last_send,
+ UI.status
+from '.USER_MAIL_NOTIFICATION_TABLE.' as N
+ JOIN '.USERS_TABLE.' as U on N.user_id = U.'.$conf['user_fields']['id'].'
+ JOIN '.USER_INFOS_TABLE.' as UI on UI.user_id = N.user_id
+where 1=1';
+
+ if ($action == 'send')
+ {
+ // No mail empty and all users enabled
+ $query .= ' and
+ N.enabled = \'true\' and
+ U.'.$conf['user_fields']['email'].' is not null';
+ }
+
+ $query .= $query_and_check_key;
+
+ if (isset($enabled_filter_value) and ($enabled_filter_value != ''))
+ {
+ $query .= ' and
+ N.enabled = \''.boolean_to_string($enabled_filter_value).'\'';
+ }
+
+ $query .= '
+order by';
+
+ if ($action == 'send')
+ {
+ $query .= '
+ last_send, username;';
+ }
+ else
+ {
+ $query .= '
+ username';
+ }
+
+ $query .= ';';
+
+ $result = pwg_query($query);
+ if (!empty($result))
+ {
+ while ($nbm_user = pwg_db_fetch_assoc($result))
+ {
+ $data_users[] = $nbm_user;
+ }
+ }
+ }
+ return $data_users;
+}
+
+/*
+ * Begin of use nbm environment
+ * Prepare and save current environment and initialize data in order to send mail
+ *
+ * Return none
+ */
+function begin_users_env_nbm($is_to_send_mail = false)
+{
+ global $user, $lang, $lang_info, $conf, $env_nbm;
+
+ // Save $user, $lang_info and $lang arrays (include/user.inc.php has been executed)
+ $env_nbm['save_user'] = $user;
+ // Save current language to stack, necessary because $user change during NBM
+ switch_lang_to($user['language']);
+
+ $env_nbm['is_to_send_mail'] = $is_to_send_mail;
+
+ if ($is_to_send_mail)
+ {
+ // Init mail configuration
+ $env_nbm['email_format'] = get_str_email_format($conf['nbm_send_html_mail']);
+ $env_nbm['send_as_name'] = ((isset($conf['nbm_send_mail_as']) and !empty($conf['nbm_send_mail_as'])) ? $conf['nbm_send_mail_as'] : get_mail_sender_name());
+ $env_nbm['send_as_mail_address'] = get_webmaster_mail_address();
+ $env_nbm['send_as_mail_formated'] = format_email($env_nbm['send_as_name'], $env_nbm['send_as_mail_address']);
+ // Init mail counter
+ $env_nbm['error_on_mail_count'] = 0;
+ $env_nbm['sent_mail_count'] = 0;
+ // Save sendmail message info and error in the original language
+ $env_nbm['msg_info'] = l10n('Mail sent to %s [%s].');
+ $env_nbm['msg_error'] = l10n('Error when sending email to %s [%s].');
+ }
+}
+
+/*
+ * End of use nbm environment
+ * Restore environment
+ *
+ * Return none
+ */
+function end_users_env_nbm()
+{
+ global $user, $lang, $lang_info, $env_nbm;
+
+ // Restore $user, $lang_info and $lang arrays (include/user.inc.php has been executed)
+ $user = $env_nbm['save_user'];
+ // Restore current language to stack, necessary because $user change during NBM
+ switch_lang_back();
+
+ if ($env_nbm['is_to_send_mail'])
+ {
+ unset($env_nbm['email_format']);
+ unset($env_nbm['send_as_name']);
+ unset($env_nbm['send_as_mail_address']);
+ unset($env_nbm['send_as_mail_formated']);
+ // Don t unset counter
+ //unset($env_nbm['error_on_mail_count']);
+ //unset($env_nbm['sent_mail_count']);
+ unset($env_nbm['msg_info']);
+ unset($env_nbm['msg_error']);
+ }
+
+ unset($env_nbm['save_user']);
+ unset($env_nbm['is_to_send_mail']);
+}
+
+/*
+ * Set user on nbm enviromnent
+ *
+ * Return none
+ */
+function set_user_on_env_nbm(&$nbm_user, $is_action_send)
+{
+ global $user, $lang, $lang_info, $env_nbm;
+
+ $user = build_user( $nbm_user['user_id'], true );
+
+ switch_lang_to($user['language']);
+
+ if ($is_action_send)
+ {
+ $env_nbm['mail_template'] = get_mail_template($env_nbm['email_format']);
+ $env_nbm['mail_template']->set_filename('notification_by_mail', 'notification_by_mail.tpl');
+ }
+}
+
+/*
+ * Unset user on nbm enviromnent
+ *
+ * Return none
+ */
+function unset_user_on_env_nbm()
+{
+ global $env_nbm;
+
+ switch_lang_back();
+ unset($env_nbm['mail_template']);
+}
+
+/*
+ * Inc Counter success
+ *
+ * Return none
+ */
+function inc_mail_sent_success($nbm_user)
+{
+ global $page, $env_nbm;
+
+ $env_nbm['sent_mail_count'] += 1;
+ $page['infos'][] = sprintf($env_nbm['msg_info'], stripslashes($nbm_user['username']), $nbm_user['mail_address']);
+}
+
+/*
+ * Inc Counter failed
+ *
+ * Return none
+ */
+function inc_mail_sent_failed($nbm_user)
+{
+ global $page, $env_nbm;
+
+ $env_nbm['error_on_mail_count'] += 1;
+ $page['errors'][] = sprintf($env_nbm['msg_error'], stripslashes($nbm_user['username']), $nbm_user['mail_address']);
+}
+
+/*
+ * Display Counter Info
+ *
+ * Return none
+ */
+function display_counter_info()
+{
+ global $page, $env_nbm;
+
+ if ($env_nbm['error_on_mail_count'] != 0)
+ {
+ $page['errors'][] = l10n_dec(
+ '%d mail was not sent.', '%d mails were not sent.',
+ $env_nbm['error_on_mail_count']
+ );
+
+ if ($env_nbm['sent_mail_count'] != 0)
+ {
+ $page['infos'][] = l10n_dec(
+ '%d mail was sent.', '%d mails were sent.',
+ $env_nbm['sent_mail_count']
+ );
+ }
+ }
+ else
+ {
+ if ($env_nbm['sent_mail_count'] == 0)
+ {
+ $page['infos'][] = l10n('No mail to send.');
+ }
+ else
+ {
+ $page['infos'][] = l10n_dec(
+ '%d mail was sent.', '%d mails were sent.',
+ $env_nbm['sent_mail_count']
+ );
+ }
+ }
+}
+
+function assign_vars_nbm_mail_content($nbm_user)
+{
+ global $env_nbm;
+
+ set_make_full_url();
+
+ $env_nbm['mail_template']->assign
+ (
+ array
+ (
+ 'USERNAME' => stripslashes($nbm_user['username']),
+
+ 'SEND_AS_NAME' => $env_nbm['send_as_name'],
+
+ 'UNSUBSCRIBE_LINK' => add_url_params(get_gallery_home_url().'/nbm.php', array('unsubscribe' => $nbm_user['check_key'])),
+ 'SUBSCRIBE_LINK' => add_url_params(get_gallery_home_url().'/nbm.php', array('subscribe' => $nbm_user['check_key'])),
+ 'CONTACT_EMAIL' => $env_nbm['send_as_mail_address']
+ )
+ );
+
+ unset_make_full_url();
+}
+
+/*
+ * Subscribe or unsubscribe notification by mail
+ *
+ * is_subscribe define if action=subscribe or unsubscribe
+ * check_key list where action will be done
+ *
+ * @return check_key list treated
+ */
+function do_subscribe_unsubscribe_notification_by_mail($is_admin_request, $is_subscribe = false, $check_key_list = array())
+{
+ global $conf, $page, $env_nbm, $conf;
+
+ set_make_full_url();
+
+ $check_key_treated = array();
+ $updated_data_count = 0;
+ $error_on_updated_data_count = 0;
+
+ if ($is_subscribe)
+ {
+ $msg_info = l10n('User %s [%s] was added to the subscription list.');
+ $msg_error = l10n('User %s [%s] was not added to the subscription list.');
+ }
+ else
+ {
+ $msg_info = l10n('User %s [%s] was removed from the subscription list.');
+ $msg_error = l10n('User %s [%s] was not removed from the subscription list.');
+ }
+
+ if (count($check_key_list) != 0)
+ {
+ $updates = array();
+ $enabled_value = boolean_to_string($is_subscribe);
+ $data_users = get_user_notifications('subscribe', $check_key_list, !$is_subscribe);
+
+ // Prepare message after change language
+ $msg_break_timeout = l10n('Time to send mail is limited. Others mails are skipped.');
+
+ // Begin nbm users environment
+ begin_users_env_nbm(true);
+
+ foreach ($data_users as $nbm_user)
+ {
+ if (check_sendmail_timeout())
+ {
+ // Stop fill list on 'send', if the quota is override
+ $page['errors'][] = $msg_break_timeout;
+ break;
+ }
+
+ // Fill return list
+ $check_key_treated[] = $nbm_user['check_key'];
+
+ $do_update = true;
+ if ($nbm_user['mail_address'] != '')
+ {
+ // set env nbm user
+ set_user_on_env_nbm($nbm_user, true);
+
+ $subject = '['.$conf['gallery_title'].'] '.($is_subscribe ? l10n('Subscribe to notification by mail'): l10n('Unsubscribe from notification by mail'));
+
+ // Assign current var for nbm mail
+ assign_vars_nbm_mail_content($nbm_user);
+
+ $section_action_by = ($is_subscribe ? 'subscribe_by_' : 'unsubscribe_by_');
+ $section_action_by .= ($is_admin_request ? 'admin' : 'himself');
+ $env_nbm['mail_template']->assign
+ (
+ array
+ (
+ $section_action_by => true,
+ 'GOTO_GALLERY_TITLE' => $conf['gallery_title'],
+ 'GOTO_GALLERY_URL' => get_gallery_home_url(),
+ )
+ );
+
+ $ret = pwg_mail(
+ array(
+ 'name' => stripslashes($nbm_user['username']),
+ 'email' => $nbm_user['mail_address'],
+ ),
+ array(
+ 'from' => $env_nbm['send_as_mail_formated'],
+ 'subject' => $subject,
+ 'email_format' => $env_nbm['email_format'],
+ 'content' => $env_nbm['mail_template']->parse('notification_by_mail', true),
+ 'content_format' => $env_nbm['email_format'],
+ )
+ );
+
+ if ($ret)
+ {
+ inc_mail_sent_success($nbm_user);
+ }
+ else
+ {
+ inc_mail_sent_failed($nbm_user);
+ $do_update = false;
+ }
+
+ // unset env nbm user
+ unset_user_on_env_nbm();
+
+ }
+
+ if ($do_update)
+ {
+ $updates[] = array(
+ 'check_key' => $nbm_user['check_key'],
+ 'enabled' => $enabled_value
+ );
+ $updated_data_count += 1;
+ $page['infos'][] = sprintf($msg_info, stripslashes($nbm_user['username']), $nbm_user['mail_address']);
+ }
+ else
+ {
+ $error_on_updated_data_count += 1;
+ $page['errors'][] = sprintf($msg_error, stripslashes($nbm_user['username']), $nbm_user['mail_address']);
+ }
+
+ }
+
+ // Restore nbm environment
+ end_users_env_nbm();
+
+ display_counter_info();
+
+ mass_updates(
+ USER_MAIL_NOTIFICATION_TABLE,
+ array(
+ 'primary' => array('check_key'),
+ 'update' => array('enabled')
+ ),
+ $updates
+ );
+
+ }
+
+ $page['infos'][] = l10n_dec(
+ '%d user was updated.', '%d users were updated.',
+ $updated_data_count
+ );
+
+ if ($error_on_updated_data_count != 0)
+ {
+ $page['errors'][] = l10n_dec(
+ '%d user was not updated.', '%d users were not updated.',
+ $error_on_updated_data_count
+ );
+ }
+
+ unset_make_full_url();
+
+ return $check_key_treated;
+}
+
+/*
+ * Unsubscribe notification by mail
+ *
+ * check_key list where action will be done
+ *
+ * @return check_key list treated
+ */
+function unsubscribe_notification_by_mail($is_admin_request, $check_key_list = array())
+{
+ return do_subscribe_unsubscribe_notification_by_mail($is_admin_request, false, $check_key_list);
+}
+
+/*
+ * Subscribe notification by mail
+ *
+ * check_key list where action will be done
+ *
+ * @return check_key list treated
+ */
+function subscribe_notification_by_mail($is_admin_request, $check_key_list = array())
+{
+ return do_subscribe_unsubscribe_notification_by_mail($is_admin_request, true, $check_key_list);
+}
+
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/include/functions_permalinks.php b/Piwingo/piwigo-data/piwigo/admin/include/functions_permalinks.php
new file mode 100644
index 0000000..e84079f
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/include/functions_permalinks.php
@@ -0,0 +1,189 @@
+
diff --git a/Piwingo/piwigo-data/piwigo/admin/include/functions_plugins.inc.php b/Piwingo/piwigo-data/piwigo/admin/include/functions_plugins.inc.php
new file mode 100644
index 0000000..67758ff
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/include/functions_plugins.inc.php
@@ -0,0 +1,31 @@
+
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/include/functions_upgrade.php b/Piwingo/piwigo-data/piwigo/admin/include/functions_upgrade.php
new file mode 100644
index 0000000..3de706d
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/include/functions_upgrade.php
@@ -0,0 +1,322 @@
+'.implode(', ', $plugins).'
';
+ }
+}
+
+// Deactivate all non-standard themes
+function deactivate_non_standard_themes()
+{
+ global $page, $conf;
+
+ $standard_themes = array(
+ 'modus',
+ 'elegant',
+ 'smartpocket',
+ );
+
+ $query = '
+SELECT
+ id,
+ name
+ FROM '.PREFIX_TABLE.'themes
+ WHERE id NOT IN (\''.implode("','", $standard_themes).'\')
+;';
+ $result = pwg_query($query);
+ $theme_ids = array();
+ $theme_names = array();
+ while ($row = pwg_db_fetch_assoc($result))
+ {
+ $theme_ids[] = $row['id'];
+ $theme_names[] = $row['name'];
+ }
+
+ if (!empty($theme_ids))
+ {
+ $query = '
+DELETE
+ FROM '.PREFIX_TABLE.'themes
+ WHERE id IN (\''.implode("','", $theme_ids).'\')
+;';
+ pwg_query($query);
+
+ $page['infos'][] = l10n('As a precaution, following themes have been deactivated. You must check for themes upgrade before reactiving them:')
+ .''.implode(', ', $theme_names).'
';
+
+ // what is the default theme?
+ $query = '
+SELECT theme
+ FROM '.PREFIX_TABLE.'user_infos
+ WHERE user_id = '.$conf['default_user_id'].'
+;';
+ list($default_theme) = pwg_db_fetch_row(pwg_query($query));
+
+ // if the default theme has just been deactivated, let's set another core theme as default
+ if (in_array($default_theme, $theme_ids))
+ {
+ // make sure default Piwigo theme is active
+ $query = '
+SELECT
+ COUNT(*)
+ FROM '.PREFIX_TABLE.'themes
+ WHERE id = \''.PHPWG_DEFAULT_TEMPLATE.'\'
+;';
+ list($counter) = pwg_db_fetch_row(pwg_query($query));
+ if ($counter < 1)
+ {
+ // we need to activate theme first
+ include_once(PHPWG_ROOT_PATH.'admin/include/themes.class.php');
+ $themes = new themes();
+ $themes->perform_action('activate', PHPWG_DEFAULT_TEMPLATE);
+ }
+
+ // then associate it to default user
+ $query = '
+UPDATE '.PREFIX_TABLE.'user_infos
+ SET theme = \''.PHPWG_DEFAULT_TEMPLATE.'\'
+ WHERE user_id = '.$conf['default_user_id'].'
+;';
+ pwg_query($query);
+ }
+ }
+}
+
+// Deactivate all templates
+function deactivate_templates()
+{
+ conf_update_param('extents_for_templates', array());
+}
+
+// Check access rights
+function check_upgrade_access_rights()
+{
+ global $conf, $page, $current_release;
+
+ if (version_compare($current_release, '2.0', '>=') and isset($_COOKIE[session_name()]))
+ {
+ // Check if user is already connected as webmaster
+ session_start();
+ if (!empty($_SESSION['pwg_uid']))
+ {
+ $query = '
+SELECT status
+ FROM '.USER_INFOS_TABLE.'
+ WHERE user_id = '.$_SESSION['pwg_uid'].'
+;';
+ pwg_query($query);
+
+ $row = pwg_db_fetch_assoc(pwg_query($query));
+ if (isset($row['status']) and $row['status'] == 'webmaster')
+ {
+ define('PHPWG_IN_UPGRADE', true);
+ return;
+ }
+ }
+ }
+
+ if (!isset($_POST['username']) or !isset($_POST['password']))
+ {
+ return;
+ }
+
+ $username = $_POST['username'];
+ $password = $_POST['password'];
+
+ if(function_exists('get_magic_quotes_gpc') && !@get_magic_quotes_gpc() )
+ {
+ $username = pwg_db_real_escape_string($username);
+ }
+
+ if (version_compare($current_release, '2.0', '<'))
+ {
+ $username = utf8_decode($username);
+ $password = utf8_decode($password);
+ }
+
+ if (version_compare($current_release, '1.5', '<'))
+ {
+ $query = '
+SELECT password, status
+FROM '.USERS_TABLE.'
+WHERE username = \''.$username.'\'
+;';
+ }
+ else
+ {
+ $query = '
+SELECT u.password, ui.status
+FROM '.USERS_TABLE.' AS u
+INNER JOIN '.USER_INFOS_TABLE.' AS ui
+ON u.'.$conf['user_fields']['id'].'=ui.user_id
+WHERE '.$conf['user_fields']['username'].'=\''.$username.'\'
+;';
+ }
+ $row = pwg_db_fetch_assoc(pwg_query($query));
+
+ if (!$conf['password_verify']($password, $row['password']))
+ {
+ $page['errors'][] = l10n('Invalid password!');
+ }
+ elseif ($row['status'] != 'admin' and $row['status'] != 'webmaster')
+ {
+ $page['errors'][] = l10n('You do not have access rights to run upgrade');
+ }
+ else
+ {
+ define('PHPWG_IN_UPGRADE', true);
+ }
+}
+
+/**
+ * which upgrades are available ?
+ *
+ * @return array
+ */
+function get_available_upgrade_ids()
+{
+ $upgrades_path = PHPWG_ROOT_PATH.'install/db';
+
+ $available_upgrade_ids = array();
+
+ if ($contents = opendir($upgrades_path))
+ {
+ while (($node = readdir($contents)) !== false)
+ {
+ if (is_file($upgrades_path.'/'.$node)
+ and preg_match('/^(.*?)-database\.php$/', $node, $match))
+ {
+ $available_upgrade_ids[] = $match[1];
+ }
+ }
+ }
+ natcasesort($available_upgrade_ids);
+
+ return $available_upgrade_ids;
+}
+
+
+/**
+ * returns true if there are available upgrade files
+ */
+function check_upgrade_feed()
+{
+ // retrieve already applied upgrades
+ $query = '
+SELECT id
+ FROM '.UPGRADE_TABLE.'
+;';
+ $applied = array_from_query($query, 'id');
+
+ // retrieve existing upgrades
+ $existing = get_available_upgrade_ids();
+
+ // which upgrades need to be applied?
+ return (count(array_diff($existing, $applied)) > 0);
+}
+
+function upgrade_db_connect()
+{
+ global $conf;
+
+ try
+ {
+ pwg_db_connect($conf['db_host'], $conf['db_user'],
+ $conf['db_password'], $conf['db_base']);
+ pwg_db_check_version();
+ }
+ catch (Exception $e)
+ {
+ my_error(l10n($e->getMessage()), true);
+ }
+}
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/include/functions_upload.inc.php b/Piwingo/piwigo-data/piwigo/admin/include/functions_upload.inc.php
new file mode 100644
index 0000000..474062b
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/include/functions_upload.inc.php
@@ -0,0 +1,1137 @@
+ array(
+ 'default' => false,
+ 'can_be_null' => false,
+ ),
+
+ 'original_resize_maxwidth' => array(
+ 'default' => 2000,
+ 'min' => 500,
+ 'max' => 20000,
+ 'pattern' => '/^\d+$/',
+ 'can_be_null' => false,
+ 'error_message' => l10n('The original maximum width must be a number between %d and %d'),
+ ),
+
+ 'original_resize_maxheight' => array(
+ 'default' => 2000,
+ 'min' => 300,
+ 'max' => 20000,
+ 'pattern' => '/^\d+$/',
+ 'can_be_null' => false,
+ 'error_message' => l10n('The original maximum height must be a number between %d and %d'),
+ ),
+
+ 'original_resize_quality' => array(
+ 'default' => 95,
+ 'min' => 50,
+ 'max' => 98,
+ 'pattern' => '/^\d+$/',
+ 'can_be_null' => false,
+ 'error_message' => l10n('The original image quality must be a number between %d and %d'),
+ ),
+ );
+
+ return $upload_form_config;
+}
+
+function save_upload_form_config($data, &$errors=array(), &$form_errors=array())
+{
+ if (!is_array($data) or empty($data))
+ {
+ return false;
+ }
+
+ $upload_form_config = get_upload_form_config();
+ $updates = array();
+
+ foreach ($data as $field => $value)
+ {
+ if (!isset($upload_form_config[$field]))
+ {
+ continue;
+ }
+ if (is_bool($upload_form_config[$field]['default']))
+ {
+ if (isset($value))
+ {
+ $value = true;
+ }
+ else
+ {
+ $value = false;
+ }
+
+ $updates[] = array(
+ 'param' => $field,
+ 'value' => boolean_to_string($value)
+ );
+ }
+ elseif ($upload_form_config[$field]['can_be_null'] and empty($value))
+ {
+ $updates[] = array(
+ 'param' => $field,
+ 'value' => 'false'
+ );
+ }
+ else
+ {
+ $min = $upload_form_config[$field]['min'];
+ $max = $upload_form_config[$field]['max'];
+ $pattern = $upload_form_config[$field]['pattern'];
+
+ if (preg_match($pattern, $value) and $value >= $min and $value <= $max)
+ {
+ $updates[] = array(
+ 'param' => $field,
+ 'value' => $value
+ );
+ }
+ else
+ {
+ $errors[] = sprintf(
+ $upload_form_config[$field]['error_message'],
+ $min, $max
+ );
+
+ $form_errors[$field] = '['.$min.' .. '.$max.']';
+ }
+ }
+ }
+
+ if (count($errors) == 0)
+ {
+ mass_updates(
+ CONFIG_TABLE,
+ array(
+ 'primary' => array('param'),
+ 'update' => array('value')
+ ),
+ $updates
+ );
+ return true;
+ }
+
+ return false;
+}
+
+function add_uploaded_file($source_filepath, $original_filename=null, $categories=null, $level=null, $image_id=null, $original_md5sum=null)
+{
+ // 1) move uploaded file to upload/2010/01/22/20100122003814-449ada00.jpg
+ //
+ // 2) keep/resize original
+ //
+ // 3) register in database
+
+ global $conf, $user, $logger;
+
+ if (!is_null($original_filename))
+ {
+ $original_filename = htmlspecialchars($original_filename);
+ }
+
+ if (isset($original_md5sum))
+ {
+ $md5sum = $original_md5sum;
+ }
+ else
+ {
+ $md5sum = md5_file($source_filepath);
+ }
+
+ // we only try to detect duplicate on a new image, not when updating an existing image
+ if (!isset($image_id) and $conf['upload_detect_duplicate'])
+ {
+ $query = '
+SELECT
+ id
+ FROM '. IMAGES_TABLE .'
+ WHERE md5sum = \''.$md5sum.'\'
+;';
+ $images_found = query2array($query);
+
+ if (count($images_found) > 0)
+ {
+ $image_id = $images_found[0]['id'];
+ $logger->info('['.__FUNCTION__.'] image already exist #'.$image_id.', we delete the newly uploaded file : '.$source_filepath);
+ unlink($source_filepath);
+
+ // if the destination category is already linked to this photo, no worry,
+ // associate_images_to_categories perfectly handles this case
+ add_uploaded_file_add_to_categories($image_id, $categories);
+
+ // TODO should we update level? If yes, then we should invalidate_user_cache
+
+ return $image_id;
+ }
+ }
+
+ $file_path = null;
+
+ if (isset($image_id))
+ {
+ // this photo already exists, we update it
+ $query = '
+SELECT
+ path
+ FROM '.IMAGES_TABLE.'
+ WHERE id = '.$image_id.'
+;';
+ $result = pwg_query($query);
+ while ($row = pwg_db_fetch_assoc($result))
+ {
+ $file_path = $row['path'];
+ }
+
+ if (!isset($file_path))
+ {
+ die('['.__FUNCTION__.'] this photo does not exist in the database');
+ }
+
+ // delete all physical files related to the photo (thumbnail, web site, HD)
+ delete_element_files(array($image_id));
+ }
+ else
+ {
+ // this photo is new
+
+ // current date
+ list($dbnow) = pwg_db_fetch_row(pwg_query('SELECT NOW();'));
+ list($year, $month, $day) = preg_split('/[^\d]/', $dbnow, 4);
+
+ // upload directory hierarchy
+ $upload_dir = sprintf(
+ PHPWG_ROOT_PATH.$conf['upload_dir'].'/%s/%s/%s',
+ $year,
+ $month,
+ $day
+ );
+
+ // compute file path
+ $date_string = preg_replace('/[^\d]/', '', $dbnow);
+ $random_string = substr($md5sum, 0, 4).'%s';
+ $filename_wo_ext = $date_string.'-'.$random_string;
+ $file_path = $upload_dir.'/'.$filename_wo_ext.'.';
+
+ list($width, $height, $type) = getimagesize($source_filepath);
+
+ if (IMAGETYPE_PNG == $type)
+ {
+ $file_path.= 'png';
+ }
+ elseif (IMAGETYPE_GIF == $type)
+ {
+ $file_path.= 'gif';
+ }
+ elseif (IMAGETYPE_JPEG == $type)
+ {
+ $file_path.= 'jpg';
+ }
+ elseif (IMAGETYPE_WEBP == $type)
+ {
+ $file_path.= 'webp';
+ }
+ elseif (isset($conf['upload_form_all_types']) and $conf['upload_form_all_types'])
+ {
+ $original_extension = strtolower(get_extension($original_filename));
+
+ if (in_array($original_extension, $conf['file_ext']))
+ {
+ $file_path.= $original_extension;
+ }
+ else
+ {
+ unlink($source_filepath);
+ die('unexpected file type');
+ }
+ }
+ else
+ {
+ unlink($source_filepath);
+ die('forbidden file type');
+ }
+
+ prepare_directory($upload_dir);
+
+ $file_path_pattern = $file_path;
+ do
+ {
+ // we generate a random string for each upload. If the user uploads
+ // the same photo twice at the same time (same timestamp, same md5sum)
+ // we still want the path to be unique.
+ $file_path = sprintf($file_path_pattern, substr(bin2hex(random_bytes(4)), 0, 4));
+ }
+ while (file_exists($file_path));
+ }
+
+ if (is_uploaded_file($source_filepath))
+ {
+ move_uploaded_file($source_filepath, $file_path);
+ }
+ else
+ {
+ rename($source_filepath, $file_path);
+ }
+ @chmod($file_path, 0644);
+
+ // handle the uploaded file type by potentially making a
+ // pwg_representative file.
+ $representative_ext = trigger_change('upload_file', null, $file_path);
+
+ $logger->info("Handling " . (string)$file_path . " got " . (string)$representative_ext);
+
+ // If it is set to either true (the file didn't need a
+ // representative generated) or false (the generation of the
+ // representative failed), set it to null because we have no
+ // representative file.
+ if (is_bool($representative_ext)) {
+ $representative_ext = null;
+ }
+
+ if (pwg_image::get_library() != 'gd')
+ {
+ if ($conf['original_resize'])
+ {
+ $need_resize = need_resize($file_path, $conf['original_resize_maxwidth'], $conf['original_resize_maxheight']);
+
+ if ($need_resize)
+ {
+ $img = new pwg_image($file_path);
+
+ $img->pwg_resize(
+ $file_path,
+ $conf['original_resize_maxwidth'],
+ $conf['original_resize_maxheight'],
+ $conf['original_resize_quality'],
+ $conf['upload_form_automatic_rotation'],
+ false
+ );
+
+ $img->destroy();
+ }
+ }
+ }
+
+ // we need to save the rotation angle in the database to compute
+ // width/height of "multisizes"
+ $rotation_angle = pwg_image::get_rotation_angle($file_path);
+ $rotation = pwg_image::get_rotation_code_from_angle($rotation_angle);
+
+ $file_infos = pwg_image_infos($file_path);
+
+ if (isset($image_id))
+ {
+ $update = array(
+ 'file' => pwg_db_real_escape_string(isset($original_filename) ? $original_filename : basename($file_path)),
+ 'filesize' => $file_infos['filesize'],
+ 'width' => $file_infos['width'],
+ 'height' => $file_infos['height'],
+ 'md5sum' => $md5sum,
+ 'added_by' => $user['id'],
+ 'rotation' => $rotation,
+ );
+
+ if (isset($level))
+ {
+ $update['level'] = $level;
+ }
+
+ single_update(
+ IMAGES_TABLE,
+ $update,
+ array('id' => $image_id)
+ );
+ }
+ else
+ {
+ // database registration
+ $file = pwg_db_real_escape_string(isset($original_filename) ? $original_filename : basename($file_path));
+ $insert = array(
+ 'file' => $file,
+ 'name' => get_name_from_file($file),
+ 'date_available' => $dbnow,
+ 'path' => preg_replace('#^'.preg_quote(PHPWG_ROOT_PATH).'#', '', $file_path),
+ 'filesize' => $file_infos['filesize'],
+ 'width' => $file_infos['width'],
+ 'height' => $file_infos['height'],
+ 'md5sum' => $md5sum,
+ 'added_by' => $user['id'],
+ 'rotation' => $rotation,
+ );
+
+ if (isset($level))
+ {
+ $insert['level'] = $level;
+ }
+
+ if (isset($representative_ext))
+ {
+ $insert['representative_ext'] = $representative_ext;
+ }
+
+ single_insert(IMAGES_TABLE, $insert);
+
+ $image_id = pwg_db_insert_id(IMAGES_TABLE);
+ pwg_activity('photo', $image_id, 'add');
+ }
+
+ add_uploaded_file_add_to_categories($image_id, $categories);
+
+ // update metadata from the uploaded file (exif/iptc)
+ if ($conf['use_exif'] and !function_exists('exif_read_data'))
+ {
+ $conf['use_exif'] = false;
+ }
+ sync_metadata(array($image_id));
+
+ // cache a derivative
+ $query = '
+SELECT
+ id,
+ path,
+ representative_ext
+ FROM '.IMAGES_TABLE.'
+ WHERE id = '.$image_id.'
+;';
+ $image_infos = pwg_db_fetch_assoc(pwg_query($query));
+ $src_image = new SrcImage($image_infos);
+
+ set_make_full_url();
+ // in case we are on uploadify.php, we have to replace the false path
+ $derivative_url = preg_replace('#admin/include/i#', 'i', DerivativeImage::url(IMG_MEDIUM, $src_image));
+ unset_make_full_url();
+
+ $logger->info(__FUNCTION__.' : force cache generation, derivative_url = '.$derivative_url);
+
+ fetchRemote($derivative_url, $dest);
+
+ trigger_notify('loc_end_add_uploaded_file', $image_infos);
+
+ return $image_id;
+}
+
+function add_uploaded_file_add_to_categories($image_id, $categories)
+{
+ global $conf;
+
+ if (!isset($conf['lounge_active']))
+ {
+ conf_update_param('lounge_active', false, true);
+ }
+
+ if (!$conf['lounge_active'])
+ {
+ // check if we need to use the lounge from now
+ list($nb_photos) = pwg_db_fetch_row(pwg_query('SELECT COUNT(*) FROM '.IMAGES_TABLE.';'));
+ if ($nb_photos >= $conf['lounge_activate_threshold'])
+ {
+ conf_update_param('lounge_active', true, true);
+ }
+ }
+
+ if (isset($categories) and count($categories) > 0)
+ {
+ if ($conf['lounge_active'])
+ {
+ fill_lounge(array($image_id), $categories);
+ }
+ else
+ {
+ associate_images_to_categories(array($image_id), $categories);
+ }
+ }
+
+ if (!$conf['lounge_active'])
+ {
+ invalidate_user_cache();
+ }
+}
+
+function add_format($source_filepath, $format_ext, $format_of)
+{
+ // 1) find infos about the extended image
+ //
+ // 2) move uploaded file to upload/2022/05/16/pwg_format/20100122003814-449ada00.cr2
+ //
+ // 3) register in database
+
+ if (!conf_get_param('enable_formats', false))
+ {
+ die('['.__FUNCTION__.'] formats are disabled');
+ }
+
+ if (!in_array($format_ext, conf_get_param('format_ext', array('cr2'))))
+ {
+ die('['.__FUNCTION__.'] unexpected format extension "'.$format_ext.'" (authorized extensions: '.implode(', ', conf_get_param('format_ext', array('cr2'))).')');
+ }
+
+ $query = '
+SELECT
+ path
+ FROM '.IMAGES_TABLE.'
+ WHERE id = '.$format_of.'
+;';
+ $images = query2array($query);
+
+ if (!isset($images[0]))
+ {
+ die('['.__FUNCTION__.'] this photo does not exist in the database');
+ }
+
+ $format_path = dirname($images[0]['path']).'/pwg_format/';
+ $format_path.= get_filename_wo_extension(basename($images[0]['path']));
+ $format_path.= '.'.$format_ext;
+
+ prepare_directory(dirname($format_path));
+
+ if (is_uploaded_file($source_filepath))
+ {
+ move_uploaded_file($source_filepath, $format_path);
+ }
+ else
+ {
+ rename($source_filepath, $format_path);
+ }
+ @chmod($format_path, 0644);
+
+ $file_infos = pwg_image_infos($format_path);
+
+ $insert = array(
+ 'image_id' => $format_of,
+ 'ext' => $format_ext,
+ 'filesize' => $file_infos['filesize'],
+ );
+
+
+ $query = '
+SELECT
+ format_id
+ FROM '.IMAGE_FORMAT_TABLE.'
+ WHERE image_id = '.$format_of.'
+ AND ext = "'.$format_ext.'"
+;';
+
+ $formats = query2array($query);
+ if($formats)
+ {
+ $set_fields = array(
+ 'filesize' => $file_infos['filesize'],
+ );
+ $where_fields = array(
+ 'format_id' => $formats[0]['format_id'],
+ 'image_id' => $format_of,
+ 'ext' => $format_ext,
+ );
+ single_update(IMAGE_FORMAT_TABLE, $set_fields, $where_fields);
+ $format_id = $formats[0]['format_id'];
+ $add_status = "update";
+ }
+ else
+ {
+ single_insert(IMAGE_FORMAT_TABLE, $insert);
+ $format_id = pwg_db_insert_id(IMAGE_FORMAT_TABLE);
+ $add_status = "add";
+ }
+
+ pwg_activity('photo', $format_of, 'edit', array('action'=>'add format', 'format_ext'=>$format_ext, 'format_id'=>$format_id));
+
+ $format_infos = $insert;
+ $format_infos['format_id'] = $format_id;
+
+ trigger_notify('loc_end_add_format', $format_infos);
+
+ return $add_status;
+}
+
+add_event_handler('upload_file', 'upload_file_pdf');
+function upload_file_pdf($representative_ext, $file_path)
+{
+ global $logger, $conf;
+
+ $logger->info(__FUNCTION__.', $file_path = '.$file_path.', $representative_ext = '.$representative_ext);
+
+ if (isset($representative_ext))
+ {
+ return $representative_ext;
+ }
+
+ if (pwg_image::get_library() != 'ext_imagick')
+ {
+ return $representative_ext;
+ }
+
+ if (!in_array(strtolower(get_extension($file_path)), array('pdf')))
+ {
+ return $representative_ext;
+ }
+
+ $ext = conf_get_param('pdf_representative_ext', 'jpg');
+ $jpg_quality = conf_get_param('pdf_jpg_quality', 90);
+
+ // move the uploaded file to pwg_representative sub-directory
+ $representative_file_path = original_to_representative($file_path, $ext);
+ prepare_directory(dirname($representative_file_path));
+
+ $exec = $conf['ext_imagick_dir'].pwg_image::get_ext_imagick_command();
+ $exec.= ' "'.realpath($file_path).'"[0]';
+ if ('jpg' == $ext)
+ {
+ $exec.= ' -quality '.$jpg_quality;
+ }
+ $exec.= ' "'.$representative_file_path.'"';
+ $exec.= ' 2>&1';
+ @exec($exec, $returnarray);
+
+ // Return the extension (if successful) or false (if failed)
+ if (file_exists($representative_file_path))
+ {
+ $representative_ext = $ext;
+ }
+
+ return $representative_ext;
+}
+
+add_event_handler('upload_file', 'upload_file_heic');
+function upload_file_heic($representative_ext, $file_path)
+{
+ global $logger, $conf;
+
+ $logger->info(__FUNCTION__.', $file_path = '.$file_path.', $representative_ext = '.$representative_ext);
+
+ if (isset($representative_ext))
+ {
+ return $representative_ext;
+ }
+
+ if (pwg_image::get_library() != 'ext_imagick')
+ {
+ return $representative_ext;
+ }
+
+ if (!in_array(strtolower(get_extension($file_path)), array('heic')))
+ {
+ return $representative_ext;
+ }
+
+ $ext = 'jpg';
+
+ // move the uploaded file to pwg_representative sub-directory
+ $representative_file_path = original_to_representative($file_path, $ext);
+ prepare_directory(dirname($representative_file_path));
+
+ list($w,$h) = get_optimal_dimensions_for_representative();
+
+ $exec = $conf['ext_imagick_dir'].pwg_image::get_ext_imagick_command();
+ $exec.= ' "'.realpath($file_path).'"';
+ $exec.= ' -sampling-factor 4:2:0 -quality 85 -interlace JPEG -colorspace sRGB -auto-orient +repage -resize "'.$w.'x'.$h.'>"';
+ $exec.= ' "'.$representative_file_path.'"';
+ $exec.= ' 2>&1';
+
+ $logger->info(__FUNCTION__.', exec = '.$exec);
+
+ @exec($exec, $returnarray);
+
+ // Return the extension (if successful) or false (if failed)
+ if (file_exists($representative_file_path))
+ {
+ $representative_ext = $ext;
+ }
+
+ return $representative_ext;
+}
+
+add_event_handler('upload_file', 'upload_file_tiff');
+function upload_file_tiff($representative_ext, $file_path)
+{
+ global $logger, $conf;
+
+ $logger->info(__FUNCTION__.', $file_path = '.$file_path.', $representative_ext = '.$representative_ext);
+
+ if (isset($representative_ext))
+ {
+ return $representative_ext;
+ }
+
+ if (pwg_image::get_library() != 'ext_imagick')
+ {
+ return $representative_ext;
+ }
+
+ if (!in_array(strtolower(get_extension($file_path)), array('tif', 'tiff')))
+ {
+ return $representative_ext;
+ }
+
+ // move the uploaded file to pwg_representative sub-directory
+ $representative_file_path = dirname($file_path).'/pwg_representative/';
+ $representative_file_path.= get_filename_wo_extension(basename($file_path)).'.';
+
+ $representative_ext = $conf['tiff_representative_ext'];
+ $representative_file_path.= $representative_ext;
+
+ prepare_directory(dirname($representative_file_path));
+
+ $exec = $conf['ext_imagick_dir'].pwg_image::get_ext_imagick_command();
+ $exec .= ' "'.realpath($file_path).'"';
+
+ if ('jpg' == $conf['tiff_representative_ext'])
+ {
+ $exec .= ' -quality 98';
+ }
+
+ $dest = pathinfo($representative_file_path);
+ $exec .= ' "'.realpath($dest['dirname']).'/'.$dest['basename'].'"';
+
+ $exec .= ' 2>&1';
+ @exec($exec, $returnarray);
+
+ // sometimes ImageMagick creates file-0.jpg (full size) + file-1.jpg
+ // (thumbnail). I don't know how to avoid it.
+ $representative_file_abspath = realpath($dest['dirname']).'/'.$dest['basename'];
+ if (!file_exists($representative_file_abspath))
+ {
+ $first_file_abspath = preg_replace(
+ '/\.'.$representative_ext.'$/',
+ '-0.'.$representative_ext,
+ $representative_file_abspath
+ );
+
+ if (file_exists($first_file_abspath))
+ {
+ rename($first_file_abspath, $representative_file_abspath);
+ }
+ }
+
+ return get_extension($representative_file_abspath);
+}
+
+add_event_handler('upload_file', 'upload_file_video');
+function upload_file_video($representative_ext, $file_path)
+{
+ global $logger, $conf;
+
+ $logger->info(__FUNCTION__.', $file_path = '.$file_path.', $representative_ext = '.$representative_ext);
+
+ if (isset($representative_ext))
+ {
+ return $representative_ext;
+ }
+
+ $ffmpeg_video_exts = array( // extensions tested with FFmpeg
+ 'wmv','mov','mkv','mp4','mpg','flv','asf','xvid','divx','mpeg',
+ 'avi','rm', 'm4v', 'ogg', 'ogv', 'webm', 'webmv',
+ );
+
+ if (!in_array(strtolower(get_extension($file_path)), $ffmpeg_video_exts))
+ {
+ return $representative_ext;
+ }
+
+ $representative_file_path = dirname($file_path).'/pwg_representative/';
+ $representative_file_path.= get_filename_wo_extension(basename($file_path)).'.';
+
+ $representative_ext = 'jpg';
+ $representative_file_path.= $representative_ext;
+
+ prepare_directory(dirname($representative_file_path));
+
+ // Get duration of video and determine time of poster
+ exec('ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1'." '$file_path'", $O, $S);
+
+ if (!empty($O[0]))
+ {
+ $second = min(floor($O[0]*10)/10, 2);
+ }
+ else
+ {
+ $second = 0; // Safest position of the poster
+ }
+
+ $logger->info(__FUNCTION__.', Poster at '.$second.'s');
+
+ // Generate poster, see https://trac.ffmpeg.org/wiki/Seeking
+ $ffmpeg = $conf['ffmpeg_dir'].'ffmpeg';
+ $ffmpeg.= ' -ss '.$second; // Fast seeking
+ $ffmpeg.= ' -i "'.$file_path.'"'; // Video file
+ $ffmpeg.= ' -frames:v 1'; // Extract one frame
+ $ffmpeg.= ' "'.$representative_file_path.'"'; // Output file
+
+ @exec($ffmpeg.' 2>&1', $FO, $FS);
+ if (!empty($FO[0]))
+ {
+ $logger->debug(__FUNCTION__.', Tried '.$ffmpeg);
+ $logger->debug($FO[0]);
+ }
+
+ // Did we generate the file ?
+ if (!file_exists($representative_file_path))
+ {
+ // Let's try with avconv if ffmpeg unavailable
+ $avconv = str_replace('ffmpeg', 'avconv', $ffmpeg);
+ @exec($avconv.' 2>&1', $AO, $AS);
+
+ if (!empty($AO[0]))
+ {
+ $logger->debug(__FUNCTION__.', Tried '.$avconv);
+ $logger->debug($AO[0]);
+ }
+ }
+
+ // Did we finally generate the file ?
+ if (!file_exists($representative_file_path))
+ {
+ return null;
+ }
+
+ return $representative_ext;
+}
+
+add_event_handler('upload_file', 'upload_file_psd');
+function upload_file_psd($representative_ext, $file_path)
+{
+ global $logger, $conf;
+
+ $logger->info(__FUNCTION__.', $file_path = '.$file_path.', $representative_ext = '.$representative_ext);
+
+ if (isset($representative_ext))
+ {
+ return $representative_ext;
+ }
+
+ if (pwg_image::get_library() != 'ext_imagick')
+ {
+ return $representative_ext;
+ }
+
+ if (!in_array(strtolower(get_extension($file_path)), array('psd')))
+ {
+ return $representative_ext;
+ }
+
+ // move the uploaded file to pwg_representative sub-directory
+ $representative_file_path = dirname($file_path).'/pwg_representative/';
+ $representative_file_path.= get_filename_wo_extension(basename($file_path)).'.';
+
+ $representative_ext = 'png';
+ $representative_file_path.= $representative_ext;
+
+ prepare_directory(dirname($representative_file_path));
+
+ $exec = $conf['ext_imagick_dir'].pwg_image::get_ext_imagick_command();
+
+ $exec .= ' "'.realpath($file_path).'"';
+
+ $dest = pathinfo($representative_file_path);
+ $exec .= ' "'.realpath($dest['dirname']).'/'.$dest['basename'].'"';
+
+ $exec .= ' 2>&1';
+ $logger->info(__FUNCTION__.', exec = '.$exec);
+ @exec($exec, $returnarray);
+
+ // sometimes ImageMagick creates file-0.png + file-1.png + file-2.png...
+ // It seems we can't avoid it.
+ $representative_file_abspath = realpath($dest['dirname']).'/'.$dest['basename'];
+ if (!file_exists($representative_file_abspath))
+ {
+ $first_file_abspath = preg_replace(
+ '/\.'.$representative_ext.'$/',
+ '-0.'.$representative_ext,
+ $representative_file_abspath
+ );
+
+ if (file_exists($first_file_abspath))
+ {
+ rename($first_file_abspath, $representative_file_abspath);
+ }
+ }
+
+ return get_extension($representative_file_abspath);
+}
+
+add_event_handler('upload_file', 'upload_file_eps');
+function upload_file_eps($representative_ext, $file_path)
+{
+ global $logger, $conf;
+
+ $logger->info(__FUNCTION__.', $file_path = '.$file_path.', $representative_ext = '.$representative_ext);
+
+ if (isset($representative_ext))
+ {
+ return $representative_ext;
+ }
+
+ if (pwg_image::get_library() != 'ext_imagick')
+ {
+ return $representative_ext;
+ }
+
+ if (!in_array(strtolower(get_extension($file_path)), array('eps')))
+ {
+ return $representative_ext;
+ }
+
+ // if the representative is "jpg", the derivatives are ugly. With "png" it's fine.
+ $ext = 'png';
+
+ // move the uploaded file to pwg_representative sub-directory
+ $representative_file_path = original_to_representative($file_path, $ext);
+ prepare_directory(dirname($representative_file_path));
+
+ // convert -density 300 image.eps -resize 2048x2048 image.png
+
+ $exec = $conf['ext_imagick_dir'].pwg_image::get_ext_imagick_command();
+ $exec.= ' "'.realpath($file_path).'"';
+ $exec.= ' -density 300';
+ $exec.= ' -resize 2048x2048';
+ $exec.= ' "'.$representative_file_path.'"';
+ $exec.= ' 2>&1';
+ $logger->info(__FUNCTION__.', $exec = '.$exec);
+ @exec($exec, $returnarray);
+
+ // Return the extension (if successful) or false (if failed)
+ if (file_exists($representative_file_path))
+ {
+ $representative_ext = $ext;
+ }
+
+ return $representative_ext;
+}
+
+function prepare_directory($directory)
+{
+ if (!is_dir($directory)) {
+ if (substr(PHP_OS, 0, 3) == 'WIN')
+ {
+ $directory = str_replace('/', DIRECTORY_SEPARATOR, $directory);
+ }
+ umask(0000);
+ $recursive = true;
+ if (!@mkdir($directory, 0777, $recursive))
+ {
+ die('[prepare_directory] cannot create directory "'.$directory.'"');
+ }
+ }
+
+ if (!is_writable($directory))
+ {
+ // last chance to make the directory writable
+ @chmod($directory, 0777);
+
+ if (!is_writable($directory))
+ {
+ die('[prepare_directory] directory "'.$directory.'" has no write access');
+ }
+ }
+
+ secure_directory($directory);
+}
+
+function need_resize($image_filepath, $max_width, $max_height)
+{
+ global $conf, $logger;
+
+ if (!in_array(strtolower(get_extension($image_filepath)), $conf['picture_ext']))
+ {
+ return false;
+ }
+
+ // TODO : the resize check should take the orientation into account. If a
+ // rotation must be applied to the resized photo, then we should test
+ // invert width and height.
+ list($width, $height) = getimagesize($image_filepath);
+
+ if ($width > $max_width or $height > $max_height)
+ {
+ $logger->info(__FUNCTION__.' '.(string)$image_filepath.' is too big (current='.$width.'x'.$height.'px Vs max='.$max_width.'x'.$max_height.'px)');
+ return true;
+ }
+
+ return false;
+}
+
+function pwg_image_infos($path)
+{
+ list($width, $height) = getimagesize($path);
+ $filesize = floor(filesize($path)/1024);
+
+ return array(
+ 'width' => $width,
+ 'height' => $height,
+ 'filesize' => $filesize,
+ );
+}
+
+function is_valid_image_extension($extension)
+{
+ global $conf;
+
+ if (isset($conf['upload_form_all_types']) and $conf['upload_form_all_types'])
+ {
+ $extensions = $conf['file_ext'];
+ }
+ else
+ {
+ $extensions = $conf['picture_ext'];
+ }
+
+ return array_unique(array_map('strtolower', $extensions));
+}
+
+function file_upload_error_message($error_code)
+{
+ switch ($error_code) {
+ case UPLOAD_ERR_INI_SIZE:
+ return sprintf(
+ l10n('The uploaded file exceeds the upload_max_filesize directive in php.ini: %sB'),
+ get_ini_size('upload_max_filesize', false)
+ );
+ case UPLOAD_ERR_FORM_SIZE:
+ return l10n('The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form');
+ case UPLOAD_ERR_PARTIAL:
+ return l10n('The uploaded file was only partially uploaded');
+ case UPLOAD_ERR_NO_FILE:
+ return l10n('No file was uploaded');
+ case UPLOAD_ERR_NO_TMP_DIR:
+ return l10n('Missing a temporary folder');
+ case UPLOAD_ERR_CANT_WRITE:
+ return l10n('Failed to write file to disk');
+ case UPLOAD_ERR_EXTENSION:
+ return l10n('File upload stopped by extension');
+ default:
+ return l10n('Unknown upload error');
+ }
+}
+
+function get_ini_size($ini_key, $in_bytes=true)
+{
+ $size = ini_get($ini_key);
+
+ if ($in_bytes)
+ {
+ $size = convert_shorthand_notation_to_bytes($size);
+ }
+
+ return $size;
+}
+
+function convert_shorthand_notation_to_bytes($value)
+{
+ $suffix = substr($value, -1);
+ $multiply_by = null;
+
+ if ('K' == $suffix)
+ {
+ $multiply_by = 1024;
+ }
+ else if ('M' == $suffix)
+ {
+ $multiply_by = 1024*1024;
+ }
+ else if ('G' == $suffix)
+ {
+ $multiply_by = 1024*1024*1024;
+ }
+
+ if (isset($multiply_by))
+ {
+ $value = substr($value, 0, -1);
+ $value*= $multiply_by;
+ }
+
+ return $value;
+}
+
+function add_upload_error($upload_id, $error_message)
+{
+ $_SESSION['uploads_error'][$upload_id][] = $error_message;
+}
+
+function ready_for_upload_message()
+{
+ global $conf;
+
+ $relative_dir = preg_replace('#^'.PHPWG_ROOT_PATH.'#', '', $conf['upload_dir']);
+
+ if (!is_dir($conf['upload_dir']))
+ {
+ if (!is_writable(dirname($conf['upload_dir'])))
+ {
+ return sprintf(
+ l10n('Create the "%s" directory at the root of your Piwigo installation'),
+ $relative_dir
+ );
+ }
+ }
+ else
+ {
+ if (!is_writable($conf['upload_dir']))
+ {
+ @chmod($conf['upload_dir'], 0777);
+
+ if (!is_writable($conf['upload_dir']))
+ {
+ return sprintf(
+ l10n('Give write access (chmod 777) to "%s" directory at the root of your Piwigo installation'),
+ $relative_dir
+ );
+ }
+ }
+ }
+
+ return null;
+}
+
+/**
+ * Return the optimized resize dimensions for a representative, based on maximum display size.
+ * There is no need to generate a 4000x3000 JPEG from a 4000x3000 HEIC if XXL size is only 1600x1200.
+ *
+ * @since 14
+ *
+ * @return array(width, height)
+ */
+function get_optimal_dimensions_for_representative()
+{
+ global $conf;
+
+ $enabled = ImageStdParams::get_defined_type_map();
+ $disabled = safe_unserialize(ImageStdParams::get_disabled_type_map());
+ if ($disabled === false)
+ {
+ $disabled = array();
+ }
+
+ $w = $h = 2000; // safe default values
+
+ foreach(ImageStdParams::get_all_types() as $type)
+ {
+ $params = $enabled[$type] ?? @$disabled[$type];
+
+ if ($params)
+ {
+ list($w, $h) = $params->sizing->ideal_size;
+ }
+ }
+
+ $margin_coef = 1.5;
+
+ return array($w*$margin_coef, $h*$margin_coef);
+}
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/include/image.class.php b/Piwingo/piwigo-data/piwigo/admin/include/image.class.php
new file mode 100644
index 0000000..67718ac
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/include/image.class.php
@@ -0,0 +1,926 @@
+source_filepath = $source_filepath;
+
+ trigger_notify('load_image_library', array(&$this) );
+
+ if (is_object($this->image))
+ {
+ return; // A plugin may have load its own library
+ }
+
+ $extension = strtolower(get_extension($source_filepath));
+
+ if (!in_array($extension, $conf['picture_ext']))
+ {
+ die('[Image] unsupported file extension');
+ }
+
+ if (!($this->library = self::get_library($library, $extension)))
+ {
+ die('No image library available on your server.');
+ }
+
+ $class = 'image_'.$this->library;
+ $this->image = new $class($source_filepath);
+ }
+
+ // Unknow methods will be redirected to image object
+ function __call($method, $arguments)
+ {
+ return call_user_func_array(array($this->image, $method), $arguments);
+ }
+
+ // Piwigo resize function
+ function pwg_resize($destination_filepath, $max_width, $max_height, $quality, $automatic_rotation=true, $strip_metadata=false, $crop=false, $follow_orientation=true)
+ {
+ $starttime = get_moment();
+
+ // width/height
+ $source_width = $this->image->get_width();
+ $source_height = $this->image->get_height();
+
+ $rotation = null;
+ if ($automatic_rotation)
+ {
+ $rotation = self::get_rotation_angle($this->source_filepath);
+ }
+ $resize_dimensions = self::get_resize_dimensions($source_width, $source_height, $max_width, $max_height, $rotation, $crop, $follow_orientation);
+
+ // testing on height is useless in theory: if width is unchanged, there
+ // should be no resize, because width/height ratio is not modified.
+ if ($resize_dimensions['width'] == $source_width and $resize_dimensions['height'] == $source_height)
+ {
+ // the image doesn't need any resize! We just copy it to the destination
+ copy($this->source_filepath, $destination_filepath);
+ return $this->get_resize_result($destination_filepath, $resize_dimensions['width'], $resize_dimensions['height'], $starttime);
+ }
+
+ $this->image->set_compression_quality($quality);
+
+ if ($strip_metadata)
+ {
+ // we save a few kilobytes. For example a thumbnail with metadata weights 25KB, without metadata 7KB.
+ $this->image->strip();
+ }
+
+ if (isset($resize_dimensions['crop']))
+ {
+ $this->image->crop($resize_dimensions['crop']['width'], $resize_dimensions['crop']['height'], $resize_dimensions['crop']['x'], $resize_dimensions['crop']['y']);
+ }
+
+ $this->image->resize($resize_dimensions['width'], $resize_dimensions['height']);
+
+ if (!empty($rotation))
+ {
+ $this->image->rotate($rotation);
+ }
+
+ $this->image->write($destination_filepath);
+
+ // everything should be OK if we are here!
+ return $this->get_resize_result($destination_filepath, $resize_dimensions['width'], $resize_dimensions['height'], $starttime);
+ }
+
+ static function get_resize_dimensions($width, $height, $max_width, $max_height, $rotation=null, $crop=false, $follow_orientation=true)
+ {
+ $rotate_for_dimensions = false;
+ if (isset($rotation) and in_array(abs($rotation), array(90, 270)))
+ {
+ $rotate_for_dimensions = true;
+ }
+
+ if ($rotate_for_dimensions)
+ {
+ list($width, $height) = array($height, $width);
+ }
+
+ if ($crop)
+ {
+ $x = 0;
+ $y = 0;
+
+ if ($width < $height and $follow_orientation)
+ {
+ list($max_width, $max_height) = array($max_height, $max_width);
+ }
+
+ $img_ratio = $width / $height;
+ $dest_ratio = $max_width / $max_height;
+
+ if($dest_ratio > $img_ratio)
+ {
+ $destHeight = round($width * $max_height / $max_width);
+ $y = round(($height - $destHeight) / 2 );
+ $height = $destHeight;
+ }
+ elseif ($dest_ratio < $img_ratio)
+ {
+ $destWidth = round($height * $max_width / $max_height);
+ $x = round(($width - $destWidth) / 2 );
+ $width = $destWidth;
+ }
+ }
+
+ $ratio_width = $width / $max_width;
+ $ratio_height = $height / $max_height;
+ $destination_width = $width;
+ $destination_height = $height;
+
+ // maximal size exceeded ?
+ if ($ratio_width > 1 or $ratio_height > 1)
+ {
+ if ($ratio_width < $ratio_height)
+ {
+ $destination_width = round($width / $ratio_height);
+ $destination_height = $max_height;
+ }
+ else
+ {
+ $destination_width = $max_width;
+ $destination_height = round($height / $ratio_width);
+ }
+ }
+
+ if ($rotate_for_dimensions)
+ {
+ list($destination_width, $destination_height) = array($destination_height, $destination_width);
+ }
+
+ $result = array(
+ 'width' => $destination_width,
+ 'height'=> $destination_height,
+ );
+
+ if ($crop and ($x or $y))
+ {
+ $result['crop'] = array(
+ 'width' => $width,
+ 'height' => $height,
+ 'x' => $x,
+ 'y' => $y,
+ );
+ }
+ return $result;
+ }
+
+ static function webp_info($source_filepath)
+ {
+ // function based on https://stackoverflow.com/questions/61221874/detect-if-a-webp-image-is-transparent-in-php
+ //
+ // https://github.com/webmproject/libwebp/blob/master/src/dec/webp_dec.c
+ // https://developers.google.com/speed/webp/docs/riff_container
+ // https://developers.google.com/speed/webp/docs/webp_lossless_bitstream_specification
+ // https://stackoverflow.com/questions/61221874/detect-if-a-webp-image-is-transparent-in-php
+
+ $fp = fopen($source_filepath, 'rb');
+ if (!$fp) {
+ throw new Exception("webp_info(): fopen($f): Failed");
+ }
+ $buf = fread($fp, 25);
+ fclose($fp);
+
+ switch (true) {
+ case!is_string($buf):
+ case strlen($buf) < 25:
+ case substr($buf, 0, 4) != 'RIFF':
+ case substr($buf, 8, 4) != 'WEBP':
+ case substr($buf, 12, 3) != 'VP8':
+ throw new Exception("webp_info(): not a valid webp image");
+
+ case $buf[15] == ' ':
+ // Simple File Format (Lossy)
+ return array(
+ 'type' => 'VP8',
+ 'has-animation' => false,
+ 'has-transparent' => false,
+ );
+
+
+ case $buf[15] == 'L':
+ // Simple File Format (Lossless)
+ return array(
+ 'type' => 'VP8L',
+ 'has-animation' => false,
+ 'has-transparent' => (bool) (!!(ord($buf[24]) & 0x00000010)),
+ );
+
+ case $buf[15] == 'X':
+ // Extended File Format
+ return array(
+ 'type' => 'VP8X',
+ 'has-animation' => (bool) (!!(ord($buf[20]) & 0x00000002)),
+ 'has-transparent' => (bool) (!!(ord($buf[20]) & 0x00000010)),
+ );
+
+ default:
+ throw new Exception("webp_info(): could not detect webp type");
+ }
+ }
+
+ static function get_rotation_angle($source_filepath)
+ {
+ list($width, $height, $type) = getimagesize($source_filepath);
+ if (IMAGETYPE_JPEG != $type)
+ {
+ return null;
+ }
+
+ if (!function_exists('exif_read_data'))
+ {
+ return null;
+ }
+
+ $rotation = 0;
+
+ $exif = @exif_read_data($source_filepath);
+
+ if (isset($exif['Orientation']) and preg_match('/^\s*(\d)/', $exif['Orientation'], $matches))
+ {
+ $orientation = $matches[1];
+ if (in_array($orientation, array(3, 4)))
+ {
+ $rotation = 180;
+ }
+ elseif (in_array($orientation, array(5, 6)))
+ {
+ $rotation = 270;
+ }
+ elseif (in_array($orientation, array(7, 8)))
+ {
+ $rotation = 90;
+ }
+ }
+
+ return $rotation;
+ }
+
+ static function get_rotation_code_from_angle($rotation_angle)
+ {
+ switch($rotation_angle)
+ {
+ case 0: return 0;
+ case 90: return 1;
+ case 180: return 2;
+ case 270: return 3;
+ }
+ }
+
+ static function get_rotation_angle_from_code($rotation_code)
+ {
+ switch($rotation_code%4)
+ {
+ case 0: return 0;
+ case 1: return 90;
+ case 2: return 180;
+ case 3: return 270;
+ }
+ }
+
+ /** Returns a normalized convolution kernel for sharpening*/
+ static function get_sharpen_matrix($amount)
+ {
+ // Amount should be in the range of 48-10
+ $amount = round(abs(-48 + ($amount * 0.38)), 2);
+
+ $matrix = array(
+ array(-1, -1, -1),
+ array(-1, $amount, -1),
+ array(-1, -1, -1),
+ );
+
+ $norm = array_sum(array_map('array_sum', $matrix));
+
+ for ($i=0; $i<3; $i++)
+ {
+ for ($j=0; $j<3; $j++)
+ {
+ $matrix[$i][$j] /= $norm;
+ }
+ }
+
+ return $matrix;
+ }
+
+ protected function get_resize_result($destination_filepath, $width, $height, $time=null)
+ {
+ return array(
+ 'source' => $this->source_filepath,
+ 'destination' => $destination_filepath,
+ 'width' => $width,
+ 'height' => $height,
+ 'size' => floor(filesize($destination_filepath) / 1024).' KB',
+ 'time' => $time ? number_format((get_moment() - $time) * 1000, 2, '.', ' ').' ms' : null,
+ 'library' => $this->library,
+ );
+ }
+
+ static function is_imagick()
+ {
+ return (extension_loaded('imagick') and class_exists('Imagick'));
+ }
+
+ static function get_ext_imagick_command()
+ {
+ global $page, $conf;
+
+ if (!isset($page['ext_imagick_command']))
+ {
+ $retval=null;
+ $cmd_out=null;
+ // check if magick is in path
+ exec('command -v '.$conf['ext_imagick_dir'].'magick', $cmd_out , $retval );
+ if (0 == $retval)
+ {
+ $page['ext_imagick_command'] = 'magick';
+ }
+ else
+ {
+ $page['ext_imagick_command'] = 'convert';
+ }
+ }
+
+ return $page['ext_imagick_command'];
+ }
+
+ static function is_ext_imagick()
+ {
+ global $conf;
+
+ if (!function_exists('exec'))
+ {
+ return false;
+ }
+
+ @exec($conf['ext_imagick_dir'].pwg_image::get_ext_imagick_command().' -version', $returnarray);
+ if (is_array($returnarray) and !empty($returnarray[0]) and preg_match('/ImageMagick/i', $returnarray[0]))
+ {
+ if (preg_match('/Version: ImageMagick (\d+\.\d+\.\d+-?\d*)/', $returnarray[0], $match))
+ {
+ self::$ext_imagick_version = $match[1];
+ }
+ return true;
+ }
+ return false;
+ }
+
+ static function is_gd()
+ {
+ return function_exists('gd_info');
+ }
+
+ static function get_library($library=null, $extension=null)
+ {
+ global $conf;
+
+ if (is_null($library))
+ {
+ $library = $conf['graphics_library'];
+ }
+
+ // Choose image library
+ switch (strtolower($library))
+ {
+ case 'auto':
+ case 'ext_imagick':
+ if ($extension != 'gif' and self::is_ext_imagick())
+ {
+ return 'ext_imagick';
+ }
+ case 'imagick':
+ if ($extension != 'gif' and self::is_imagick())
+ {
+ return 'imagick';
+ }
+ case 'gd':
+ if (self::is_gd())
+ {
+ return 'gd';
+ }
+ default:
+ if ($library != 'auto')
+ {
+ // Requested library not available. Try another library
+ return self::get_library('auto', $extension);
+ }
+ }
+ return false;
+ }
+
+ function destroy()
+ {
+ if (method_exists($this->image, 'destroy'))
+ {
+ return $this->image->destroy();
+ }
+ return true;
+ }
+}
+
+// +-----------------------------------------------------------------------+
+// | Class for Imagick extension |
+// +-----------------------------------------------------------------------+
+
+class image_imagick implements imageInterface
+{
+ var $image;
+
+ function __construct($source_filepath)
+ {
+ // A bug cause that Imagick class can not be extended
+ $this->image = new Imagick($source_filepath);
+ }
+
+ function get_width()
+ {
+ return $this->image->getImageWidth();
+ }
+
+ function get_height()
+ {
+ return $this->image->getImageHeight();
+ }
+
+ function set_compression_quality($quality)
+ {
+ return $this->image->setImageCompressionQuality($quality);
+ }
+
+ function crop($width, $height, $x, $y)
+ {
+ return $this->image->cropImage($width, $height, $x, $y);
+ }
+
+ function strip()
+ {
+ return $this->image->stripImage();
+ }
+
+ function rotate($rotation)
+ {
+ $this->image->rotateImage(new ImagickPixel(), -$rotation);
+ $this->image->setImageOrientation(Imagick::ORIENTATION_TOPLEFT);
+ return true;
+ }
+
+ function resize($width, $height)
+ {
+ $this->image->setInterlaceScheme(Imagick::INTERLACE_LINE);
+
+ // TODO need to explain this condition
+ if ($this->get_width()%2 == 0
+ && $this->get_height()%2 == 0
+ && $this->get_width() > 3*$width)
+ {
+ $this->image->scaleImage($this->get_width()/2, $this->get_height()/2);
+ }
+
+ return $this->image->resizeImage($width, $height, Imagick::FILTER_LANCZOS, 0.9);
+ }
+
+ function sharpen($amount)
+ {
+ $m = pwg_image::get_sharpen_matrix($amount);
+ return $this->image->convolveImage($m);
+ }
+
+ function compose($overlay, $x, $y, $opacity)
+ {
+ $ioverlay = $overlay->image->image;
+ /*if ($ioverlay->getImageAlphaChannel() !== Imagick::ALPHACHANNEL_OPAQUE)
+ {
+ // Force the image to have an alpha channel
+ $ioverlay->setImageAlphaChannel(Imagick::ALPHACHANNEL_OPAQUE);
+ }*/
+
+ global $dirty_trick_xrepeat;
+ if ( !isset($dirty_trick_xrepeat) && $opacity < 100)
+ {// NOTE: Using setImageOpacity will destroy current alpha channels!
+ $ioverlay->evaluateImage(Imagick::EVALUATE_MULTIPLY, $opacity / 100, Imagick::CHANNEL_ALPHA);
+ $dirty_trick_xrepeat = true;
+ }
+
+ return $this->image->compositeImage($ioverlay, Imagick::COMPOSITE_DISSOLVE, $x, $y);
+ }
+
+ function write($destination_filepath)
+ {
+ // use 4:2:2 chroma subsampling (reduce file size by 20-30% with "almost" no human perception)
+ $this->image->setSamplingFactors( array(2,1) );
+ return $this->image->writeImage($destination_filepath);
+ }
+}
+
+// +-----------------------------------------------------------------------+
+// | Class for ImageMagick external installation |
+// +-----------------------------------------------------------------------+
+
+class image_ext_imagick implements imageInterface
+{
+ var $imagickdir = '';
+ var $source_filepath = '';
+ var $width = '';
+ var $height = '';
+ var $is_animated_webp = false;
+ var $commands = array();
+
+ function __construct($source_filepath)
+ {
+ global $conf;
+ $this->source_filepath = $source_filepath;
+ $this->imagickdir = $conf['ext_imagick_dir'];
+
+ if (strpos(@$_SERVER['SCRIPT_FILENAME'], '/kunden/') === 0) // 1and1
+ {
+ @putenv('MAGICK_THREAD_LIMIT=1');
+ }
+
+ if ('webp' == strtolower(get_extension($source_filepath)))
+ {
+ $webp_info = pwg_image::webp_info($source_filepath);
+
+ if ($webp_info['has-animation'])
+ {
+ $this->is_animated_webp = true;
+
+ // ImageMagick "identify" returns the list of width x height for each
+ // frame, such as "400x300400x300400x300" (3 frames of 400x300), as a big
+ // string, impossible to parse :-/ So let's use the PHP embedded function
+ // getimagesize here.
+ list($this->width, $this->height) = getimagesize($source_filepath);
+ return;
+ }
+ }
+
+ $command = $this->imagickdir.'identify -format "%wx%h" "'.realpath($source_filepath).'"';
+ @exec($command, $returnarray);
+ if(!is_array($returnarray) or empty($returnarray[0]) or !preg_match('/^(\d+)x(\d+)$/', $returnarray[0], $match))
+ {
+ die("[External ImageMagick] Corrupt image\n" . var_export($returnarray, true));
+ }
+
+ $this->width = $match[1];
+ $this->height = $match[2];
+ }
+
+ function add_command($command, $params=null)
+ {
+ $this->commands[$command] = $params;
+ }
+
+ function get_width()
+ {
+ return $this->width;
+ }
+
+ function get_height()
+ {
+ return $this->height;
+ }
+
+ function crop($width, $height, $x, $y)
+ {
+ $this->width = $width;
+ $this->height = $height;
+
+ // the final "!" is added to crop the canva too, for animated picture (with WebP in mind)
+ $this->add_command('crop', $width.'x'.$height.'+'.$x.'+'.$y.'!');
+ return true;
+ }
+
+ function strip()
+ {
+ $this->add_command('strip');
+ return true;
+ }
+
+ function rotate($rotation)
+ {
+ if (empty($rotation))
+ {
+ return true;
+ }
+
+ if ($rotation==90 || $rotation==270)
+ {
+ $tmp = $this->width;
+ $this->width = $this->height;
+ $this->height = $tmp;
+ }
+ $this->add_command('rotate', -$rotation);
+ $this->add_command('orient', 'top-left');
+ return true;
+ }
+
+ function set_compression_quality($quality)
+ {
+ global $conf;
+
+ if ($this->is_animated_webp)
+ {
+ // in cas of animated WebP, we need to maximize quality to 70 to avoid
+ // heavy thumbnails (or square or whatever is displayed on the thumbnails
+ // page)
+ $quality = min($quality, $conf['animated_webp_compression_quality']);
+ }
+
+ $this->add_command('quality', $quality);
+ return true;
+ }
+
+ function resize($width, $height)
+ {
+ $this->width = $width;
+ $this->height = $height;
+
+ $this->add_command('filter', 'Lanczos');
+ $this->add_command('resize', $width.'x'.$height.'!');
+ return true;
+ }
+
+ function sharpen($amount)
+ {
+ $m = pwg_image::get_sharpen_matrix($amount);
+
+ $param ='convolve "'.count($m).':';
+ foreach ($m as $line)
+ {
+ $param .= ' ';
+ $param .= implode(',', $line);
+ }
+ $param .= '"';
+ $this->add_command('morphology', $param);
+ return true;
+ }
+
+ function compose($overlay, $x, $y, $opacity)
+ {
+ $param = 'compose dissolve -define compose:args='.$opacity;
+ $param .= ' '.escapeshellarg(realpath($overlay->image->source_filepath));
+ $param .= ' -gravity NorthWest -geometry +'.$x.'+'.$y;
+ $param .= ' -composite';
+ $this->add_command($param);
+ return true;
+ }
+
+ function write($destination_filepath)
+ {
+ global $logger;
+
+ $this->add_command('interlace', 'line'); // progressive rendering
+ // use 4:2:2 chroma subsampling (reduce file size by 20-30% with "almost" no human perception)
+ //
+ // option deactivated for Piwigo 2.4.1, it doesn't work fo old versions
+ // of ImageMagick, see bug:2672. To reactivate once we have a better way
+ // to detect IM version and when we know which version supports this
+ // option
+ //
+ if (version_compare(pwg_image::$ext_imagick_version, '6.6') > 0)
+ {
+ $this->add_command('sampling-factor', '4:2:2' );
+ }
+
+ $exec = $this->imagickdir.pwg_image::get_ext_imagick_command();
+ $exec .= ' "'.realpath($this->source_filepath).'"';
+
+ // If the image is animated webp add a filter to avoid breaking the animation
+ if ($this->is_animated_webp)
+ {
+ $exec .= ' -layers coalesce ';
+ }
+
+ foreach ($this->commands as $command => $params)
+ {
+ $exec .= ' -'.$command;
+ if (!empty($params))
+ {
+ $exec .= ' '.$params;
+ }
+ }
+ $dest = pathinfo($destination_filepath);
+ $exec .= ' "'.realpath($dest['dirname']).'/'.$dest['basename'].'" 2>&1';
+ $logger->debug($exec, 'i.php');
+ @exec($exec, $returnarray);
+
+ if (is_array($returnarray) && (count($returnarray)>0) )
+ {
+ $logger->error('', 'i.php', $returnarray);
+ foreach ($returnarray as $line)
+ trigger_error($line, E_USER_WARNING);
+ }
+ return is_array($returnarray);
+ }
+}
+
+// +-----------------------------------------------------------------------+
+// | Class for GD library |
+// +-----------------------------------------------------------------------+
+
+class image_gd implements imageInterface
+{
+ var $image;
+ var $quality = 95;
+
+ function __construct($source_filepath)
+ {
+ $gd_info = gd_info();
+ $extension = strtolower(get_extension($source_filepath));
+
+ if (in_array($extension, array('jpg', 'jpeg')))
+ {
+ $this->image = imagecreatefromjpeg($source_filepath);
+ }
+ else if ($extension == 'png')
+ {
+ $this->image = imagecreatefrompng($source_filepath);
+ }
+ elseif ($extension == 'gif' and $gd_info['GIF Read Support'] and $gd_info['GIF Create Support'])
+ {
+ $this->image = imagecreatefromgif($source_filepath);
+ }
+ else
+ {
+ die('[Image GD] unsupported file extension');
+ }
+ }
+
+ function get_width()
+ {
+ return imagesx($this->image);
+ }
+
+ function get_height()
+ {
+ return imagesy($this->image);
+ }
+
+ function crop($width, $height, $x, $y)
+ {
+ $dest = imagecreatetruecolor($width, $height);
+
+ imagealphablending($dest, false);
+ imagesavealpha($dest, true);
+ if (function_exists('imageantialias'))
+ {
+ imageantialias($dest, true);
+ }
+
+ $result = imagecopymerge($dest, $this->image, 0, 0, $x, $y, $width, $height, 100);
+
+ if ($result !== false)
+ {
+ imagedestroy($this->image);
+ $this->image = $dest;
+ }
+ else
+ {
+ imagedestroy($dest);
+ }
+ return $result;
+ }
+
+ function strip()
+ {
+ return true;
+ }
+
+ function rotate($rotation)
+ {
+ $dest = imagerotate($this->image, $rotation, 0);
+ imagedestroy($this->image);
+ $this->image = $dest;
+ return true;
+ }
+
+ function set_compression_quality($quality)
+ {
+ $this->quality = $quality;
+ return true;
+ }
+
+ function resize($width, $height)
+ {
+ $dest = imagecreatetruecolor($width, $height);
+
+ imagealphablending($dest, false);
+ imagesavealpha($dest, true);
+ if (function_exists('imageantialias'))
+ {
+ imageantialias($dest, true);
+ }
+
+ $result = imagecopyresampled($dest, $this->image, 0, 0, 0, 0, $width, $height, $this->get_width(), $this->get_height());
+
+ if ($result !== false)
+ {
+ imagedestroy($this->image);
+ $this->image = $dest;
+ }
+ else
+ {
+ imagedestroy($dest);
+ }
+ return $result;
+ }
+
+ function sharpen($amount)
+ {
+ $m = pwg_image::get_sharpen_matrix($amount);
+ return imageconvolution($this->image, $m, 1, 0);
+ }
+
+ function compose($overlay, $x, $y, $opacity)
+ {
+ $ioverlay = $overlay->image->image;
+ /* A replacement for php's imagecopymerge() function that supports the alpha channel
+ See php bug #23815: http://bugs.php.net/bug.php?id=23815 */
+
+ $ow = imagesx($ioverlay);
+ $oh = imagesy($ioverlay);
+
+ // Create a new blank image the site of our source image
+ $cut = imagecreatetruecolor($ow, $oh);
+
+ // Copy the blank image into the destination image where the source goes
+ imagecopy($cut, $this->image, 0, 0, $x, $y, $ow, $oh);
+
+ // Place the source image in the destination image
+ imagecopy($cut, $ioverlay, 0, 0, 0, 0, $ow, $oh);
+ imagecopymerge($this->image, $cut, $x, $y, 0, 0, $ow, $oh, $opacity);
+ imagedestroy($cut);
+ return true;
+ }
+
+ function write($destination_filepath)
+ {
+ $extension = strtolower(get_extension($destination_filepath));
+
+ if ($extension == 'png')
+ {
+ imagepng($this->image, $destination_filepath);
+ }
+ elseif ($extension == 'gif')
+ {
+ imagegif($this->image, $destination_filepath);
+ }
+ else
+ {
+ imagejpeg($this->image, $destination_filepath, $this->quality);
+ }
+ }
+
+ function destroy()
+ {
+ imagedestroy($this->image);
+ }
+}
+
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/include/index.php b/Piwingo/piwigo-data/piwigo/admin/include/index.php
new file mode 100644
index 0000000..58ea04e
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/include/index.php
@@ -0,0 +1,15 @@
+
diff --git a/Piwingo/piwigo-data/piwigo/admin/include/languages.class.php b/Piwingo/piwigo-data/piwigo/admin/include/languages.class.php
new file mode 100644
index 0000000..5dc846f
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/include/languages.class.php
@@ -0,0 +1,431 @@
+get_fs_languages($target_charset);
+ }
+
+ /**
+ * Perform requested actions
+ * @param string - action
+ * @param string - language id
+ * @param array - errors
+ */
+ function perform_action($action, $language_id)
+ {
+ global $conf;
+
+ if (!$conf['enable_extensions_install'] and 'delete' == $action)
+ {
+ die('Piwigo extensions install/update/delete system is disabled');
+ }
+
+ if (isset($this->db_languages[$language_id]))
+ {
+ $crt_db_language = $this->db_languages[$language_id];
+ }
+
+ $errors = array();
+
+ switch ($action)
+ {
+ case 'activate':
+ if (isset($crt_db_language))
+ {
+ $errors[] = 'CANNOT ACTIVATE - LANGUAGE IS ALREADY ACTIVATED';
+ break;
+ }
+
+ $query = '
+INSERT INTO '.LANGUAGES_TABLE.'
+ (id, version, name)
+ VALUES(\''.$language_id.'\',
+ \''.$this->fs_languages[$language_id]['version'].'\',
+ \''.$this->fs_languages[$language_id]['name'].'\')
+;';
+ pwg_query($query);
+ break;
+
+ case 'deactivate':
+ if (!isset($crt_db_language))
+ {
+ $errors[] = 'CANNOT DEACTIVATE - LANGUAGE IS ALREADY DEACTIVATED';
+ break;
+ }
+
+ if ($language_id == get_default_language())
+ {
+ $errors[] = 'CANNOT DEACTIVATE - LANGUAGE IS DEFAULT LANGUAGE';
+ break;
+ }
+
+ $query = '
+DELETE
+ FROM '.LANGUAGES_TABLE.'
+ WHERE id= \''.$language_id.'\'
+;';
+ pwg_query($query);
+ break;
+
+ case 'delete':
+ if (!empty($crt_db_language))
+ {
+ $errors[] = 'CANNOT DELETE - LANGUAGE IS ACTIVATED';
+ break;
+ }
+ if (!isset($this->fs_languages[$language_id]))
+ {
+ $errors[] = 'CANNOT DELETE - LANGUAGE DOES NOT EXIST';
+ break;
+ }
+
+ // Set default language to user who are using this language
+ $query = '
+UPDATE '.USER_INFOS_TABLE.'
+ SET language = \''.get_default_language().'\'
+ WHERE language = \''.$language_id.'\'
+;';
+ pwg_query($query);
+
+ deltree(PHPWG_ROOT_PATH.'language/'.$language_id, PHPWG_ROOT_PATH.'language/trash');
+ break;
+
+ case 'set_default':
+ $query = '
+UPDATE '.USER_INFOS_TABLE.'
+ SET language = \''.$language_id.'\'
+ WHERE user_id IN ('.$conf['default_user_id'].', '.$conf['guest_id'].')
+;';
+ pwg_query($query);
+ break;
+ }
+ return $errors;
+ }
+
+ /**
+ * Get languages defined in the language directory
+ */
+ function get_fs_languages($target_charset = null)
+ {
+ if ( empty($target_charset) )
+ {
+ $target_charset = get_pwg_charset();
+ }
+ $target_charset = strtolower($target_charset);
+
+ $dir = opendir(PHPWG_ROOT_PATH.'language');
+ while ($file = readdir($dir))
+ {
+ if ($file!='.' and $file!='..')
+ {
+ $path = PHPWG_ROOT_PATH.'language/'.$file;
+ if (is_dir($path) and !is_link($path)
+ and preg_match('/^[a-zA-Z0-9-_]+$/', $file )
+ and file_exists($path.'/common.lang.php')
+ )
+ {
+ $language = array(
+ 'name'=>$file,
+ 'code'=>$file,
+ 'version'=>'0',
+ 'uri'=>'',
+ 'author'=>'',
+ );
+ $plg_data = implode( '', file($path.'/common.lang.php') );
+
+ if (preg_match("|Language Name:\\s*(.+)|", $plg_data, $val))
+ {
+ $language['name'] = trim( $val[1] );
+ $language['name'] = convert_charset($language['name'], 'utf-8', $target_charset);
+ }
+ if (preg_match("|Version:\\s*([\\w.-]+)|", $plg_data, $val))
+ {
+ $language['version'] = trim($val[1]);
+ }
+ if (preg_match("|Language URI:\\s*(https?:\\/\\/.+)|", $plg_data, $val))
+ {
+ $language['uri'] = trim($val[1]);
+ }
+ if (preg_match("|Author:\\s*(.+)|", $plg_data, $val))
+ {
+ $language['author'] = trim($val[1]);
+ }
+ if (preg_match("|Author URI:\\s*(https?:\\/\\/.+)|", $plg_data, $val))
+ {
+ $language['author uri'] = trim($val[1]);
+ }
+ if (!empty($language['uri']) and strpos($language['uri'] , 'extension_view.php?eid='))
+ {
+ list( , $extension) = explode('extension_view.php?eid=', $language['uri']);
+ if (is_numeric($extension)) $language['extension'] = $extension;
+ }
+
+ // IMPORTANT SECURITY !
+ $language = array_map('htmlspecialchars', $language);
+ $this->fs_languages[$file] = $language;
+ }
+ }
+ }
+ closedir($dir);
+ @uasort($this->fs_languages, 'name_compare');
+ }
+
+ function get_db_languages()
+ {
+ $query = '
+ SELECT id, name
+ FROM '.LANGUAGES_TABLE.'
+ ORDER BY name ASC
+ ;';
+ $result = pwg_query($query);
+
+ while ($row = pwg_db_fetch_assoc($result))
+ {
+ $this->db_languages[ $row['id'] ] = $row['name'];
+ }
+ }
+
+ /**
+ * Retrieve PEM server datas to $server_languages
+ */
+ function get_server_languages($new=false)
+ {
+ global $user, $conf;
+
+ $get_data = array(
+ 'category_id' => $conf['pem_languages_category'],
+ 'format' => 'php',
+ );
+
+ // Retrieve PEM versions
+ $version = PHPWG_VERSION;
+ $versions_to_check = array();
+ $url = PEM_URL . '/api/get_version_list.php';
+ if (fetchRemote($url, $result, $get_data) and $pem_versions = @unserialize($result))
+ {
+ if (!preg_match('/^\d+\.\d+\.\d+$/', $version))
+ {
+ $version = $pem_versions[0]['name'];
+ }
+ $branch = get_branch_from_version($version);
+ foreach ($pem_versions as $pem_version)
+ {
+ if (strpos($pem_version['name'], $branch) === 0)
+ {
+ $versions_to_check[] = $pem_version['id'];
+ }
+ }
+ }
+ if (empty($versions_to_check))
+ {
+ return false;
+ }
+
+ // Languages to check
+ $languages_to_check = array();
+ foreach($this->fs_languages as $fs_language)
+ {
+ if (isset($fs_language['extension']))
+ {
+ $languages_to_check[] = $fs_language['extension'];
+ }
+ }
+
+ // Retrieve PEM languages infos
+ $url = PEM_URL . '/api/get_revision_list.php';
+ $get_data = array_merge($get_data, array(
+ 'last_revision_only' => 'true',
+ 'version' => implode(',', $versions_to_check),
+ 'lang' => $user['language'],
+ 'get_nb_downloads' => 'true',
+ )
+ );
+ if (!empty($languages_to_check))
+ {
+ if ($new)
+ {
+ $get_data['extension_exclude'] = implode(',', $languages_to_check);
+ }
+ else
+ {
+ $get_data['extension_include'] = implode(',', $languages_to_check);
+ }
+ }
+
+ if (fetchRemote($url, $result, $get_data))
+ {
+ $pem_languages = @unserialize($result);
+ if (!is_array($pem_languages))
+ {
+ return false;
+ }
+ foreach ($pem_languages as $language)
+ {
+ if (preg_match('/^.*? \[[A-Z]{2}\]$/', $language['extension_name']))
+ {
+ $this->server_languages[$language['extension_id']] = $language;
+ }
+ }
+ @uasort($this->server_languages, array($this, 'extension_name_compare'));
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Extract language files from archive
+ *
+ * @param string - install or upgrade
+ * @param string - remote revision identifier (numeric)
+ * @param string - language id or extension id
+ */
+ function extract_language_files($action, $revision, $dest='')
+ {
+ global $logger;
+
+ if ($archive = tempnam( PHPWG_ROOT_PATH.'language', 'zip'))
+ {
+ $url = PEM_URL . '/download.php';
+ $get_data = array(
+ 'rid' => $revision,
+ 'origin' => 'piwigo_'.$action,
+ );
+
+ if ($handle = @fopen($archive, 'wb') and fetchRemote($url, $handle, $get_data))
+ {
+ fclose($handle);
+ include_once(PHPWG_ROOT_PATH.'admin/include/pclzip.lib.php');
+ $zip = new PclZip($archive);
+ if ($list = $zip->listContent())
+ {
+ foreach ($list as $file)
+ {
+ // we search common.lang.php in archive
+ if (basename($file['filename']) == 'common.lang.php'
+ and (!isset($main_filepath)
+ or strlen($file['filename']) < strlen($main_filepath)))
+ {
+ $main_filepath = $file['filename'];
+ }
+ }
+
+ $logger->debug(__FUNCTION__.', $main_filepath = '.$main_filepath);
+
+ if (isset($main_filepath))
+ {
+ $root = basename(dirname($main_filepath)); // common.lang.php path in archive
+ if (preg_match('/^[a-z]{2}_[A-Z]{2}$/', $root))
+ {
+ if ($action == 'install')
+ {
+ $dest = $root;
+ }
+ $extract_path = PHPWG_ROOT_PATH.'language/'.$dest;
+
+ $logger->debug(__FUNCTION__.', $extract_path = '.$extract_path);
+
+ if (
+ $result = $zip->extract(
+ PCLZIP_OPT_PATH, $extract_path,
+ PCLZIP_OPT_REMOVE_PATH, $root,
+ PCLZIP_OPT_REPLACE_NEWER
+ )
+ )
+ {
+ foreach ($result as $file)
+ {
+ if ($file['stored_filename'] == $main_filepath)
+ {
+ $status = $file['status'];
+ break;
+ }
+ }
+ if ($status == 'ok')
+ {
+ $this->get_fs_languages();
+ if ($action == 'install')
+ {
+ $this->perform_action('activate', $dest);
+ }
+ }
+ if (file_exists($extract_path.'/obsolete.list')
+ and $old_files = file($extract_path.'/obsolete.list', FILE_IGNORE_NEW_LINES)
+ and !empty($old_files))
+ {
+ $old_files[] = 'obsolete.list';
+ $logger->debug(__FUNCTION__.', $old_files = {'.join('},{', $old_files).'}');
+
+ $extract_path_realpath = realpath($extract_path);
+
+ foreach($old_files as $old_file)
+ {
+ $old_file = trim($old_file);
+ $old_file = trim($old_file, '/'); // prevent path starting with a "/"
+
+ if (empty($old_file)) // empty here means the extension itself
+ {
+ continue;
+ }
+
+ $path = $extract_path.'/'.$old_file;
+
+ // make sure the obsolete file is withing the extension directory, prevent traversal path
+ $realpath = realpath($path);
+ if ($realpath === false or strpos($realpath, $extract_path_realpath) !== 0)
+ {
+ continue;
+ }
+
+ $logger->debug(__FUNCTION__.', to delete = '.$path);
+
+ if (is_file($path))
+ {
+ @unlink($path);
+ }
+ elseif (is_dir($path))
+ {
+ deltree($path, PHPWG_ROOT_PATH.'language/trash');
+ }
+ }
+ }
+ }
+ else $status = 'extract_error';
+ }
+ else $status = 'archive_error';
+ }
+ else $status = 'archive_error';
+ }
+ else $status = 'archive_error';
+ }
+ else $status = 'dl_archive_error';
+ }
+ else $status = 'temp_path_error';
+
+ @unlink($archive);
+ return $status;
+ }
+
+ /**
+ * Sort functions
+ */
+ function extension_name_compare($a, $b)
+ {
+ return strcmp(strtolower($a['extension_name']), strtolower($b['extension_name']));
+ }
+}
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/include/pclzip.lib.php b/Piwingo/piwigo-data/piwigo/admin/include/pclzip.lib.php
new file mode 100644
index 0000000..215a9f6
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/include/pclzip.lib.php
@@ -0,0 +1,5695 @@
+zipname = $p_zipname;
+ $this->zip_fd = 0;
+ $this->magic_quotes_status = -1;
+
+ // ----- Return
+ return;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function :
+ // create($p_filelist, $p_add_dir="", $p_remove_dir="")
+ // create($p_filelist, $p_option, $p_option_value, ...)
+ // Description :
+ // This method supports two different synopsis. The first one is historical.
+ // This method creates a Zip Archive. The Zip file is created in the
+ // filesystem. The files and directories indicated in $p_filelist
+ // are added in the archive. See the parameters description for the
+ // supported format of $p_filelist.
+ // When a directory is in the list, the directory and its content is added
+ // in the archive.
+ // In this synopsis, the function takes an optional variable list of
+ // options. See bellow the supported options.
+ // Parameters :
+ // $p_filelist : An array containing file or directory names, or
+ // a string containing one filename or one directory name, or
+ // a string containing a list of filenames and/or directory
+ // names separated by spaces.
+ // $p_add_dir : A path to add before the real path of the archived file,
+ // in order to have it memorized in the archive.
+ // $p_remove_dir : A path to remove from the real path of the file to archive,
+ // in order to have a shorter path memorized in the archive.
+ // When $p_add_dir and $p_remove_dir are set, $p_remove_dir
+ // is removed first, before $p_add_dir is added.
+ // Options :
+ // PCLZIP_OPT_ADD_PATH :
+ // PCLZIP_OPT_REMOVE_PATH :
+ // PCLZIP_OPT_REMOVE_ALL_PATH :
+ // PCLZIP_OPT_COMMENT :
+ // PCLZIP_CB_PRE_ADD :
+ // PCLZIP_CB_POST_ADD :
+ // Return Values :
+ // 0 on failure,
+ // The list of the added files, with a status of the add action.
+ // (see PclZip::listContent() for list entry format)
+ // --------------------------------------------------------------------------------
+ function create($p_filelist)
+ {
+ $v_result=1;
+
+ // ----- Reset the error handler
+ $this->privErrorReset();
+
+ // ----- Set default values
+ $v_options = array();
+ $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
+
+ // ----- Look for variable options arguments
+ $v_size = func_num_args();
+
+ // ----- Look for arguments
+ if ($v_size > 1) {
+ // ----- Get the arguments
+ $v_arg_list = func_get_args();
+
+ // ----- Remove from the options list the first argument
+ array_shift($v_arg_list);
+ $v_size--;
+
+ // ----- Look for first arg
+ if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
+
+ // ----- Parse the options
+ $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
+ array (PCLZIP_OPT_REMOVE_PATH => 'optional',
+ PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
+ PCLZIP_OPT_ADD_PATH => 'optional',
+ PCLZIP_CB_PRE_ADD => 'optional',
+ PCLZIP_CB_POST_ADD => 'optional',
+ PCLZIP_OPT_NO_COMPRESSION => 'optional',
+ PCLZIP_OPT_COMMENT => 'optional',
+ PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
+ PCLZIP_OPT_TEMP_FILE_ON => 'optional',
+ PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
+ //, PCLZIP_OPT_CRYPT => 'optional'
+ ));
+ if ($v_result != 1) {
+ return 0;
+ }
+ }
+
+ // ----- Look for 2 args
+ // Here we need to support the first historic synopsis of the
+ // method.
+ else {
+
+ // ----- Get the first argument
+ $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0];
+
+ // ----- Look for the optional second argument
+ if ($v_size == 2) {
+ $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
+ }
+ else if ($v_size > 2) {
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
+ "Invalid number / type of arguments");
+ return 0;
+ }
+ }
+ }
+
+ // ----- Look for default option values
+ $this->privOptionDefaultThreshold($v_options);
+
+ // ----- Init
+ $v_string_list = array();
+ $v_att_list = array();
+ $v_filedescr_list = array();
+ $p_result_list = array();
+
+ // ----- Look if the $p_filelist is really an array
+ if (is_array($p_filelist)) {
+
+ // ----- Look if the first element is also an array
+ // This will mean that this is a file description entry
+ if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
+ $v_att_list = $p_filelist;
+ }
+
+ // ----- The list is a list of string names
+ else {
+ $v_string_list = $p_filelist;
+ }
+ }
+
+ // ----- Look if the $p_filelist is a string
+ else if (is_string($p_filelist)) {
+ // ----- Create a list from the string
+ $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
+ }
+
+ // ----- Invalid variable type for $p_filelist
+ else {
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist");
+ return 0;
+ }
+
+ // ----- Reformat the string list
+ if (sizeof($v_string_list) != 0) {
+ foreach ($v_string_list as $v_string) {
+ if ($v_string != '') {
+ $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
+ }
+ else {
+ }
+ }
+ }
+
+ // ----- For each file in the list check the attributes
+ $v_supported_attributes
+ = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
+ ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
+ ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
+ ,PCLZIP_ATT_FILE_MTIME => 'optional'
+ ,PCLZIP_ATT_FILE_CONTENT => 'optional'
+ ,PCLZIP_ATT_FILE_COMMENT => 'optional'
+ );
+ foreach ($v_att_list as $v_entry) {
+ $v_result = $this->privFileDescrParseAtt($v_entry,
+ $v_filedescr_list[],
+ $v_options,
+ $v_supported_attributes);
+ if ($v_result != 1) {
+ return 0;
+ }
+ }
+
+ // ----- Expand the filelist (expand directories)
+ $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
+ if ($v_result != 1) {
+ return 0;
+ }
+
+ // ----- Call the create fct
+ $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options);
+ if ($v_result != 1) {
+ return 0;
+ }
+
+ // ----- Return
+ return $p_result_list;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function :
+ // add($p_filelist, $p_add_dir="", $p_remove_dir="")
+ // add($p_filelist, $p_option, $p_option_value, ...)
+ // Description :
+ // This method supports two synopsis. The first one is historical.
+ // This methods add the list of files in an existing archive.
+ // If a file with the same name already exists, it is added at the end of the
+ // archive, the first one is still present.
+ // If the archive does not exist, it is created.
+ // Parameters :
+ // $p_filelist : An array containing file or directory names, or
+ // a string containing one filename or one directory name, or
+ // a string containing a list of filenames and/or directory
+ // names separated by spaces.
+ // $p_add_dir : A path to add before the real path of the archived file,
+ // in order to have it memorized in the archive.
+ // $p_remove_dir : A path to remove from the real path of the file to archive,
+ // in order to have a shorter path memorized in the archive.
+ // When $p_add_dir and $p_remove_dir are set, $p_remove_dir
+ // is removed first, before $p_add_dir is added.
+ // Options :
+ // PCLZIP_OPT_ADD_PATH :
+ // PCLZIP_OPT_REMOVE_PATH :
+ // PCLZIP_OPT_REMOVE_ALL_PATH :
+ // PCLZIP_OPT_COMMENT :
+ // PCLZIP_OPT_ADD_COMMENT :
+ // PCLZIP_OPT_PREPEND_COMMENT :
+ // PCLZIP_CB_PRE_ADD :
+ // PCLZIP_CB_POST_ADD :
+ // Return Values :
+ // 0 on failure,
+ // The list of the added files, with a status of the add action.
+ // (see PclZip::listContent() for list entry format)
+ // --------------------------------------------------------------------------------
+ function add($p_filelist)
+ {
+ $v_result=1;
+
+ // ----- Reset the error handler
+ $this->privErrorReset();
+
+ // ----- Set default values
+ $v_options = array();
+ $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
+
+ // ----- Look for variable options arguments
+ $v_size = func_num_args();
+
+ // ----- Look for arguments
+ if ($v_size > 1) {
+ // ----- Get the arguments
+ $v_arg_list = func_get_args();
+
+ // ----- Remove form the options list the first argument
+ array_shift($v_arg_list);
+ $v_size--;
+
+ // ----- Look for first arg
+ if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
+
+ // ----- Parse the options
+ $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
+ array (PCLZIP_OPT_REMOVE_PATH => 'optional',
+ PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
+ PCLZIP_OPT_ADD_PATH => 'optional',
+ PCLZIP_CB_PRE_ADD => 'optional',
+ PCLZIP_CB_POST_ADD => 'optional',
+ PCLZIP_OPT_NO_COMPRESSION => 'optional',
+ PCLZIP_OPT_COMMENT => 'optional',
+ PCLZIP_OPT_ADD_COMMENT => 'optional',
+ PCLZIP_OPT_PREPEND_COMMENT => 'optional',
+ PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
+ PCLZIP_OPT_TEMP_FILE_ON => 'optional',
+ PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
+ //, PCLZIP_OPT_CRYPT => 'optional'
+ ));
+ if ($v_result != 1) {
+ return 0;
+ }
+ }
+
+ // ----- Look for 2 args
+ // Here we need to support the first historic synopsis of the
+ // method.
+ else {
+
+ // ----- Get the first argument
+ $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0];
+
+ // ----- Look for the optional second argument
+ if ($v_size == 2) {
+ $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
+ }
+ else if ($v_size > 2) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
+
+ // ----- Return
+ return 0;
+ }
+ }
+ }
+
+ // ----- Look for default option values
+ $this->privOptionDefaultThreshold($v_options);
+
+ // ----- Init
+ $v_string_list = array();
+ $v_att_list = array();
+ $v_filedescr_list = array();
+ $p_result_list = array();
+
+ // ----- Look if the $p_filelist is really an array
+ if (is_array($p_filelist)) {
+
+ // ----- Look if the first element is also an array
+ // This will mean that this is a file description entry
+ if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
+ $v_att_list = $p_filelist;
+ }
+
+ // ----- The list is a list of string names
+ else {
+ $v_string_list = $p_filelist;
+ }
+ }
+
+ // ----- Look if the $p_filelist is a string
+ else if (is_string($p_filelist)) {
+ // ----- Create a list from the string
+ $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
+ }
+
+ // ----- Invalid variable type for $p_filelist
+ else {
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist");
+ return 0;
+ }
+
+ // ----- Reformat the string list
+ if (sizeof($v_string_list) != 0) {
+ foreach ($v_string_list as $v_string) {
+ $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
+ }
+ }
+
+ // ----- For each file in the list check the attributes
+ $v_supported_attributes
+ = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
+ ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
+ ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
+ ,PCLZIP_ATT_FILE_MTIME => 'optional'
+ ,PCLZIP_ATT_FILE_CONTENT => 'optional'
+ ,PCLZIP_ATT_FILE_COMMENT => 'optional'
+ );
+ foreach ($v_att_list as $v_entry) {
+ $v_result = $this->privFileDescrParseAtt($v_entry,
+ $v_filedescr_list[],
+ $v_options,
+ $v_supported_attributes);
+ if ($v_result != 1) {
+ return 0;
+ }
+ }
+
+ // ----- Expand the filelist (expand directories)
+ $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
+ if ($v_result != 1) {
+ return 0;
+ }
+
+ // ----- Call the create fct
+ $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options);
+ if ($v_result != 1) {
+ return 0;
+ }
+
+ // ----- Return
+ return $p_result_list;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : listContent()
+ // Description :
+ // This public method, gives the list of the files and directories, with their
+ // properties.
+ // The properties of each entries in the list are (used also in other functions) :
+ // filename : Name of the file. For a create or add action it is the filename
+ // given by the user. For an extract function it is the filename
+ // of the extracted file.
+ // stored_filename : Name of the file / directory stored in the archive.
+ // size : Size of the stored file.
+ // compressed_size : Size of the file's data compressed in the archive
+ // (without the headers overhead)
+ // mtime : Last known modification date of the file (UNIX timestamp)
+ // comment : Comment associated with the file
+ // folder : true | false
+ // index : index of the file in the archive
+ // status : status of the action (depending of the action) :
+ // Values are :
+ // ok : OK !
+ // filtered : the file / dir is not extracted (filtered by user)
+ // already_a_directory : the file can not be extracted because a
+ // directory with the same name already exists
+ // write_protected : the file can not be extracted because a file
+ // with the same name already exists and is
+ // write protected
+ // newer_exist : the file was not extracted because a newer file exists
+ // path_creation_fail : the file is not extracted because the folder
+ // does not exist and can not be created
+ // write_error : the file was not extracted because there was a
+ // error while writing the file
+ // read_error : the file was not extracted because there was a error
+ // while reading the file
+ // invalid_header : the file was not extracted because of an archive
+ // format error (bad file header)
+ // Note that each time a method can continue operating when there
+ // is an action error on a file, the error is only logged in the file status.
+ // Return Values :
+ // 0 on an unrecoverable failure,
+ // The list of the files in the archive.
+ // --------------------------------------------------------------------------------
+ function listContent()
+ {
+ $v_result=1;
+
+ // ----- Reset the error handler
+ $this->privErrorReset();
+
+ // ----- Check archive
+ if (!$this->privCheckFormat()) {
+ return(0);
+ }
+
+ // ----- Call the extracting fct
+ $p_list = array();
+ if (($v_result = $this->privList($p_list)) != 1)
+ {
+ unset($p_list);
+ return(0);
+ }
+
+ // ----- Return
+ return $p_list;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function :
+ // extract($p_path="./", $p_remove_path="")
+ // extract([$p_option, $p_option_value, ...])
+ // Description :
+ // This method supports two synopsis. The first one is historical.
+ // This method extract all the files / directories from the archive to the
+ // folder indicated in $p_path.
+ // If you want to ignore the 'root' part of path of the memorized files
+ // you can indicate this in the optional $p_remove_path parameter.
+ // By default, if a newer file with the same name already exists, the
+ // file is not extracted.
+ //
+ // If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions
+ // are used, the path indicated in PCLZIP_OPT_ADD_PATH is append
+ // at the end of the path value of PCLZIP_OPT_PATH.
+ // Parameters :
+ // $p_path : Path where the files and directories are to be extracted
+ // $p_remove_path : First part ('root' part) of the memorized path
+ // (if any similar) to remove while extracting.
+ // Options :
+ // PCLZIP_OPT_PATH :
+ // PCLZIP_OPT_ADD_PATH :
+ // PCLZIP_OPT_REMOVE_PATH :
+ // PCLZIP_OPT_REMOVE_ALL_PATH :
+ // PCLZIP_CB_PRE_EXTRACT :
+ // PCLZIP_CB_POST_EXTRACT :
+ // Return Values :
+ // 0 or a negative value on failure,
+ // The list of the extracted files, with a status of the action.
+ // (see PclZip::listContent() for list entry format)
+ // --------------------------------------------------------------------------------
+ function extract()
+ {
+ $v_result=1;
+
+ // ----- Reset the error handler
+ $this->privErrorReset();
+
+ // ----- Check archive
+ if (!$this->privCheckFormat()) {
+ return(0);
+ }
+
+ // ----- Set default values
+ $v_options = array();
+// $v_path = "./";
+ $v_path = '';
+ $v_remove_path = "";
+ $v_remove_all_path = false;
+
+ // ----- Look for variable options arguments
+ $v_size = func_num_args();
+
+ // ----- Default values for option
+ $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
+
+ // ----- Look for arguments
+ if ($v_size > 0) {
+ // ----- Get the arguments
+ $v_arg_list = func_get_args();
+
+ // ----- Look for first arg
+ if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
+
+ // ----- Parse the options
+ $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
+ array (PCLZIP_OPT_PATH => 'optional',
+ PCLZIP_OPT_REMOVE_PATH => 'optional',
+ PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
+ PCLZIP_OPT_ADD_PATH => 'optional',
+ PCLZIP_CB_PRE_EXTRACT => 'optional',
+ PCLZIP_CB_POST_EXTRACT => 'optional',
+ PCLZIP_OPT_SET_CHMOD => 'optional',
+ PCLZIP_OPT_BY_NAME => 'optional',
+ PCLZIP_OPT_BY_EREG => 'optional',
+ PCLZIP_OPT_BY_PREG => 'optional',
+ PCLZIP_OPT_BY_INDEX => 'optional',
+ PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
+ PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional',
+ PCLZIP_OPT_REPLACE_NEWER => 'optional'
+ ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
+ ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
+ PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
+ PCLZIP_OPT_TEMP_FILE_ON => 'optional',
+ PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
+ ));
+ if ($v_result != 1) {
+ return 0;
+ }
+
+ // ----- Set the arguments
+ if (isset($v_options[PCLZIP_OPT_PATH])) {
+ $v_path = $v_options[PCLZIP_OPT_PATH];
+ }
+ if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
+ $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
+ }
+ if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
+ $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
+ }
+ if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
+ // ----- Check for '/' in last path char
+ if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
+ $v_path .= '/';
+ }
+ $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
+ }
+ }
+
+ // ----- Look for 2 args
+ // Here we need to support the first historic synopsis of the
+ // method.
+ else {
+
+ // ----- Get the first argument
+ $v_path = $v_arg_list[0];
+
+ // ----- Look for the optional second argument
+ if ($v_size == 2) {
+ $v_remove_path = $v_arg_list[1];
+ }
+ else if ($v_size > 2) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
+
+ // ----- Return
+ return 0;
+ }
+ }
+ }
+
+ // ----- Look for default option values
+ $this->privOptionDefaultThreshold($v_options);
+
+ // ----- Trace
+
+ // ----- Call the extracting fct
+ $p_list = array();
+ $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path,
+ $v_remove_all_path, $v_options);
+ if ($v_result < 1) {
+ unset($p_list);
+ return(0);
+ }
+
+ // ----- Return
+ return $p_list;
+ }
+ // --------------------------------------------------------------------------------
+
+
+ // --------------------------------------------------------------------------------
+ // Function :
+ // extractByIndex($p_index, $p_path="./", $p_remove_path="")
+ // extractByIndex($p_index, [$p_option, $p_option_value, ...])
+ // Description :
+ // This method supports two synopsis. The first one is historical.
+ // This method is doing a partial extract of the archive.
+ // The extracted files or folders are identified by their index in the
+ // archive (from 0 to n).
+ // Note that if the index identify a folder, only the folder entry is
+ // extracted, not all the files included in the archive.
+ // Parameters :
+ // $p_index : A single index (integer) or a string of indexes of files to
+ // extract. The form of the string is "0,4-6,8-12" with only numbers
+ // and '-' for range or ',' to separate ranges. No spaces or ';'
+ // are allowed.
+ // $p_path : Path where the files and directories are to be extracted
+ // $p_remove_path : First part ('root' part) of the memorized path
+ // (if any similar) to remove while extracting.
+ // Options :
+ // PCLZIP_OPT_PATH :
+ // PCLZIP_OPT_ADD_PATH :
+ // PCLZIP_OPT_REMOVE_PATH :
+ // PCLZIP_OPT_REMOVE_ALL_PATH :
+ // PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and
+ // not as files.
+ // The resulting content is in a new field 'content' in the file
+ // structure.
+ // This option must be used alone (any other options are ignored).
+ // PCLZIP_CB_PRE_EXTRACT :
+ // PCLZIP_CB_POST_EXTRACT :
+ // Return Values :
+ // 0 on failure,
+ // The list of the extracted files, with a status of the action.
+ // (see PclZip::listContent() for list entry format)
+ // --------------------------------------------------------------------------------
+ //function extractByIndex($p_index, options...)
+ function extractByIndex($p_index)
+ {
+ $v_result=1;
+
+ // ----- Reset the error handler
+ $this->privErrorReset();
+
+ // ----- Check archive
+ if (!$this->privCheckFormat()) {
+ return(0);
+ }
+
+ // ----- Set default values
+ $v_options = array();
+// $v_path = "./";
+ $v_path = '';
+ $v_remove_path = "";
+ $v_remove_all_path = false;
+
+ // ----- Look for variable options arguments
+ $v_size = func_num_args();
+
+ // ----- Default values for option
+ $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
+
+ // ----- Look for arguments
+ if ($v_size > 1) {
+ // ----- Get the arguments
+ $v_arg_list = func_get_args();
+
+ // ----- Remove form the options list the first argument
+ array_shift($v_arg_list);
+ $v_size--;
+
+ // ----- Look for first arg
+ if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
+
+ // ----- Parse the options
+ $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
+ array (PCLZIP_OPT_PATH => 'optional',
+ PCLZIP_OPT_REMOVE_PATH => 'optional',
+ PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
+ PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
+ PCLZIP_OPT_ADD_PATH => 'optional',
+ PCLZIP_CB_PRE_EXTRACT => 'optional',
+ PCLZIP_CB_POST_EXTRACT => 'optional',
+ PCLZIP_OPT_SET_CHMOD => 'optional',
+ PCLZIP_OPT_REPLACE_NEWER => 'optional'
+ ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
+ ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
+ PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
+ PCLZIP_OPT_TEMP_FILE_ON => 'optional',
+ PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
+ ));
+ if ($v_result != 1) {
+ return 0;
+ }
+
+ // ----- Set the arguments
+ if (isset($v_options[PCLZIP_OPT_PATH])) {
+ $v_path = $v_options[PCLZIP_OPT_PATH];
+ }
+ if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
+ $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
+ }
+ if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
+ $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
+ }
+ if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
+ // ----- Check for '/' in last path char
+ if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
+ $v_path .= '/';
+ }
+ $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
+ }
+ if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) {
+ $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
+ }
+ else {
+ }
+ }
+
+ // ----- Look for 2 args
+ // Here we need to support the first historic synopsis of the
+ // method.
+ else {
+
+ // ----- Get the first argument
+ $v_path = $v_arg_list[0];
+
+ // ----- Look for the optional second argument
+ if ($v_size == 2) {
+ $v_remove_path = $v_arg_list[1];
+ }
+ else if ($v_size > 2) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
+
+ // ----- Return
+ return 0;
+ }
+ }
+ }
+
+ // ----- Trace
+
+ // ----- Trick
+ // Here I want to reuse extractByRule(), so I need to parse the $p_index
+ // with privParseOptions()
+ $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index);
+ $v_options_trick = array();
+ $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick,
+ array (PCLZIP_OPT_BY_INDEX => 'optional' ));
+ if ($v_result != 1) {
+ return 0;
+ }
+ $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX];
+
+ // ----- Look for default option values
+ $this->privOptionDefaultThreshold($v_options);
+
+ // ----- Call the extracting fct
+ if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) {
+ return(0);
+ }
+
+ // ----- Return
+ return $p_list;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function :
+ // delete([$p_option, $p_option_value, ...])
+ // Description :
+ // This method removes files from the archive.
+ // If no parameters are given, then all the archive is emptied.
+ // Parameters :
+ // None or optional arguments.
+ // Options :
+ // PCLZIP_OPT_BY_INDEX :
+ // PCLZIP_OPT_BY_NAME :
+ // PCLZIP_OPT_BY_EREG :
+ // PCLZIP_OPT_BY_PREG :
+ // Return Values :
+ // 0 on failure,
+ // The list of the files which are still present in the archive.
+ // (see PclZip::listContent() for list entry format)
+ // --------------------------------------------------------------------------------
+ function delete()
+ {
+ $v_result=1;
+
+ // ----- Reset the error handler
+ $this->privErrorReset();
+
+ // ----- Check archive
+ if (!$this->privCheckFormat()) {
+ return(0);
+ }
+
+ // ----- Set default values
+ $v_options = array();
+
+ // ----- Look for variable options arguments
+ $v_size = func_num_args();
+
+ // ----- Look for arguments
+ if ($v_size > 0) {
+ // ----- Get the arguments
+ $v_arg_list = func_get_args();
+
+ // ----- Parse the options
+ $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
+ array (PCLZIP_OPT_BY_NAME => 'optional',
+ PCLZIP_OPT_BY_EREG => 'optional',
+ PCLZIP_OPT_BY_PREG => 'optional',
+ PCLZIP_OPT_BY_INDEX => 'optional' ));
+ if ($v_result != 1) {
+ return 0;
+ }
+ }
+
+ // ----- Magic quotes trick
+ $this->privDisableMagicQuotes();
+
+ // ----- Call the delete fct
+ $v_list = array();
+ if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) {
+ $this->privSwapBackMagicQuotes();
+ unset($v_list);
+ return(0);
+ }
+
+ // ----- Magic quotes trick
+ $this->privSwapBackMagicQuotes();
+
+ // ----- Return
+ return $v_list;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : deleteByIndex()
+ // Description :
+ // ***** Deprecated *****
+ // delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered.
+ // --------------------------------------------------------------------------------
+ function deleteByIndex($p_index)
+ {
+
+ $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index);
+
+ // ----- Return
+ return $p_list;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : properties()
+ // Description :
+ // This method gives the properties of the archive.
+ // The properties are :
+ // nb : Number of files in the archive
+ // comment : Comment associated with the archive file
+ // status : not_exist, ok
+ // Parameters :
+ // None
+ // Return Values :
+ // 0 on failure,
+ // An array with the archive properties.
+ // --------------------------------------------------------------------------------
+ function properties()
+ {
+
+ // ----- Reset the error handler
+ $this->privErrorReset();
+
+ // ----- Magic quotes trick
+ $this->privDisableMagicQuotes();
+
+ // ----- Check archive
+ if (!$this->privCheckFormat()) {
+ $this->privSwapBackMagicQuotes();
+ return(0);
+ }
+
+ // ----- Default properties
+ $v_prop = array();
+ $v_prop['comment'] = '';
+ $v_prop['nb'] = 0;
+ $v_prop['status'] = 'not_exist';
+
+ // ----- Look if file exists
+ if (@is_file($this->zipname))
+ {
+ // ----- Open the zip file
+ if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
+ {
+ $this->privSwapBackMagicQuotes();
+
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
+
+ // ----- Return
+ return 0;
+ }
+
+ // ----- Read the central directory informations
+ $v_central_dir = array();
+ if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
+ {
+ $this->privSwapBackMagicQuotes();
+ return 0;
+ }
+
+ // ----- Close the zip file
+ $this->privCloseFd();
+
+ // ----- Set the user attributes
+ $v_prop['comment'] = $v_central_dir['comment'];
+ $v_prop['nb'] = $v_central_dir['entries'];
+ $v_prop['status'] = 'ok';
+ }
+
+ // ----- Magic quotes trick
+ $this->privSwapBackMagicQuotes();
+
+ // ----- Return
+ return $v_prop;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : duplicate()
+ // Description :
+ // This method creates an archive by copying the content of an other one. If
+ // the archive already exist, it is replaced by the new one without any warning.
+ // Parameters :
+ // $p_archive : The filename of a valid archive, or
+ // a valid PclZip object.
+ // Return Values :
+ // 1 on success.
+ // 0 or a negative value on error (error code).
+ // --------------------------------------------------------------------------------
+ function duplicate($p_archive)
+ {
+ $v_result = 1;
+
+ // ----- Reset the error handler
+ $this->privErrorReset();
+
+ // ----- Look if the $p_archive is a PclZip object
+ if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip'))
+ {
+
+ // ----- Duplicate the archive
+ $v_result = $this->privDuplicate($p_archive->zipname);
+ }
+
+ // ----- Look if the $p_archive is a string (so a filename)
+ else if (is_string($p_archive))
+ {
+
+ // ----- Check that $p_archive is a valid zip file
+ // TBC : Should also check the archive format
+ if (!is_file($p_archive)) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'");
+ $v_result = PCLZIP_ERR_MISSING_FILE;
+ }
+ else {
+ // ----- Duplicate the archive
+ $v_result = $this->privDuplicate($p_archive);
+ }
+ }
+
+ // ----- Invalid variable
+ else
+ {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
+ $v_result = PCLZIP_ERR_INVALID_PARAMETER;
+ }
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : merge()
+ // Description :
+ // This method merge the $p_archive_to_add archive at the end of the current
+ // one ($this).
+ // If the archive ($this) does not exist, the merge becomes a duplicate.
+ // If the $p_archive_to_add archive does not exist, the merge is a success.
+ // Parameters :
+ // $p_archive_to_add : It can be directly the filename of a valid zip archive,
+ // or a PclZip object archive.
+ // Return Values :
+ // 1 on success,
+ // 0 or negative values on error (see below).
+ // --------------------------------------------------------------------------------
+ function merge($p_archive_to_add)
+ {
+ $v_result = 1;
+
+ // ----- Reset the error handler
+ $this->privErrorReset();
+
+ // ----- Check archive
+ if (!$this->privCheckFormat()) {
+ return(0);
+ }
+
+ // ----- Look if the $p_archive_to_add is a PclZip object
+ if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip'))
+ {
+
+ // ----- Merge the archive
+ $v_result = $this->privMerge($p_archive_to_add);
+ }
+
+ // ----- Look if the $p_archive_to_add is a string (so a filename)
+ else if (is_string($p_archive_to_add))
+ {
+
+ // ----- Create a temporary archive
+ $v_object_archive = new PclZip($p_archive_to_add);
+
+ // ----- Merge the archive
+ $v_result = $this->privMerge($v_object_archive);
+ }
+
+ // ----- Invalid variable
+ else
+ {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
+ $v_result = PCLZIP_ERR_INVALID_PARAMETER;
+ }
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+
+
+ // --------------------------------------------------------------------------------
+ // Function : errorCode()
+ // Description :
+ // Parameters :
+ // --------------------------------------------------------------------------------
+ function errorCode()
+ {
+ if (PCLZIP_ERROR_EXTERNAL == 1) {
+ return(PclErrorCode());
+ }
+ else {
+ return($this->error_code);
+ }
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : errorName()
+ // Description :
+ // Parameters :
+ // --------------------------------------------------------------------------------
+ function errorName($p_with_code=false)
+ {
+ $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR',
+ PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL',
+ PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL',
+ PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER',
+ PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE',
+ PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG',
+ PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP',
+ PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE',
+ PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL',
+ PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION',
+ PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT',
+ PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL',
+ PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL',
+ PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM',
+ PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP',
+ PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE',
+ PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE',
+ PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION',
+ PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION'
+ ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE'
+ ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION'
+ );
+
+ if (isset($v_name[$this->error_code])) {
+ $v_value = $v_name[$this->error_code];
+ }
+ else {
+ $v_value = 'NoName';
+ }
+
+ if ($p_with_code) {
+ return($v_value.' ('.$this->error_code.')');
+ }
+ else {
+ return($v_value);
+ }
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : errorInfo()
+ // Description :
+ // Parameters :
+ // --------------------------------------------------------------------------------
+ function errorInfo($p_full=false)
+ {
+ if (PCLZIP_ERROR_EXTERNAL == 1) {
+ return(PclErrorString());
+ }
+ else {
+ if ($p_full) {
+ return($this->errorName(true)." : ".$this->error_string);
+ }
+ else {
+ return($this->error_string." [code ".$this->error_code."]");
+ }
+ }
+ }
+ // --------------------------------------------------------------------------------
+
+
+// --------------------------------------------------------------------------------
+// ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS *****
+// ***** *****
+// ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY *****
+// --------------------------------------------------------------------------------
+
+
+
+ // --------------------------------------------------------------------------------
+ // Function : privCheckFormat()
+ // Description :
+ // This method check that the archive exists and is a valid zip archive.
+ // Several level of check exists. (futur)
+ // Parameters :
+ // $p_level : Level of check. Default 0.
+ // 0 : Check the first bytes (magic codes) (default value))
+ // 1 : 0 + Check the central directory (futur)
+ // 2 : 1 + Check each file header (futur)
+ // Return Values :
+ // true on success,
+ // false on error, the error code is set.
+ // --------------------------------------------------------------------------------
+ function privCheckFormat($p_level=0)
+ {
+ $v_result = true;
+
+ // ----- Reset the file system cache
+ clearstatcache();
+
+ // ----- Reset the error handler
+ $this->privErrorReset();
+
+ // ----- Look if the file exits
+ if (!is_file($this->zipname)) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'");
+ return(false);
+ }
+
+ // ----- Check that the file is readeable
+ if (!is_readable($this->zipname)) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'");
+ return(false);
+ }
+
+ // ----- Check the magic code
+ // TBC
+
+ // ----- Check the central header
+ // TBC
+
+ // ----- Check each file header
+ // TBC
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privParseOptions()
+ // Description :
+ // This internal methods reads the variable list of arguments ($p_options_list,
+ // $p_size) and generate an array with the options and values ($v_result_list).
+ // $v_requested_options contains the options that can be present and those that
+ // must be present.
+ // $v_requested_options is an array, with the option value as key, and 'optional',
+ // or 'mandatory' as value.
+ // Parameters :
+ // See above.
+ // Return Values :
+ // 1 on success.
+ // 0 on failure.
+ // --------------------------------------------------------------------------------
+ function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false)
+ {
+ $v_result=1;
+
+ // ----- Read the options
+ $i=0;
+ while ($i<$p_size) {
+
+ // ----- Check if the option is supported
+ if (!isset($v_requested_options[$p_options_list[$i]])) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method");
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Look for next option
+ switch ($p_options_list[$i]) {
+ // ----- Look for options that request a path value
+ case PCLZIP_OPT_PATH :
+ case PCLZIP_OPT_REMOVE_PATH :
+ case PCLZIP_OPT_ADD_PATH :
+ // ----- Check the number of parameters
+ if (($i+1) >= $p_size) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Get the value
+ $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);
+ $i++;
+ break;
+
+ case PCLZIP_OPT_TEMP_FILE_THRESHOLD :
+ // ----- Check the number of parameters
+ if (($i+1) >= $p_size) {
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+ return PclZip::errorCode();
+ }
+
+ // ----- Check for incompatible options
+ if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
+ return PclZip::errorCode();
+ }
+
+ // ----- Check the value
+ $v_value = $p_options_list[$i+1];
+ if ((!is_integer($v_value)) || ($v_value<0)) {
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+ return PclZip::errorCode();
+ }
+
+ // ----- Get the value (and convert it in bytes)
+ $v_result_list[$p_options_list[$i]] = $v_value*1048576;
+ $i++;
+ break;
+
+ case PCLZIP_OPT_TEMP_FILE_ON :
+ // ----- Check for incompatible options
+ if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
+ return PclZip::errorCode();
+ }
+
+ $v_result_list[$p_options_list[$i]] = true;
+ break;
+
+ case PCLZIP_OPT_TEMP_FILE_OFF :
+ // ----- Check for incompatible options
+ if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) {
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'");
+ return PclZip::errorCode();
+ }
+ // ----- Check for incompatible options
+ if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'");
+ return PclZip::errorCode();
+ }
+
+ $v_result_list[$p_options_list[$i]] = true;
+ break;
+
+ case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION :
+ // ----- Check the number of parameters
+ if (($i+1) >= $p_size) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Get the value
+ if ( is_string($p_options_list[$i+1])
+ && ($p_options_list[$i+1] != '')) {
+ $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);
+ $i++;
+ }
+ else {
+ }
+ break;
+
+ // ----- Look for options that request an array of string for value
+ case PCLZIP_OPT_BY_NAME :
+ // ----- Check the number of parameters
+ if (($i+1) >= $p_size) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Get the value
+ if (is_string($p_options_list[$i+1])) {
+ $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1];
+ }
+ else if (is_array($p_options_list[$i+1])) {
+ $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
+ }
+ else {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+ $i++;
+ break;
+
+ // ----- Look for options that request an EREG or PREG expression
+ case PCLZIP_OPT_BY_EREG :
+ // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG
+ // to PCLZIP_OPT_BY_PREG
+ $p_options_list[$i] = PCLZIP_OPT_BY_PREG;
+ case PCLZIP_OPT_BY_PREG :
+ //case PCLZIP_OPT_CRYPT :
+ // ----- Check the number of parameters
+ if (($i+1) >= $p_size) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Get the value
+ if (is_string($p_options_list[$i+1])) {
+ $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
+ }
+ else {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+ $i++;
+ break;
+
+ // ----- Look for options that takes a string
+ case PCLZIP_OPT_COMMENT :
+ case PCLZIP_OPT_ADD_COMMENT :
+ case PCLZIP_OPT_PREPEND_COMMENT :
+ // ----- Check the number of parameters
+ if (($i+1) >= $p_size) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE,
+ "Missing parameter value for option '"
+ .PclZipUtilOptionText($p_options_list[$i])
+ ."'");
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Get the value
+ if (is_string($p_options_list[$i+1])) {
+ $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
+ }
+ else {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE,
+ "Wrong parameter value for option '"
+ .PclZipUtilOptionText($p_options_list[$i])
+ ."'");
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+ $i++;
+ break;
+
+ // ----- Look for options that request an array of index
+ case PCLZIP_OPT_BY_INDEX :
+ // ----- Check the number of parameters
+ if (($i+1) >= $p_size) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Get the value
+ $v_work_list = array();
+ if (is_string($p_options_list[$i+1])) {
+
+ // ----- Remove spaces
+ $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', '');
+
+ // ----- Parse items
+ $v_work_list = explode(",", $p_options_list[$i+1]);
+ }
+ else if (is_integer($p_options_list[$i+1])) {
+ $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1];
+ }
+ else if (is_array($p_options_list[$i+1])) {
+ $v_work_list = $p_options_list[$i+1];
+ }
+ else {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Reduce the index list
+ // each index item in the list must be a couple with a start and
+ // an end value : [0,3], [5-5], [8-10], ...
+ // ----- Check the format of each item
+ $v_sort_flag=false;
+ $v_sort_value=0;
+ for ($j=0; $j= $p_size) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Get the value
+ $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
+ $i++;
+ break;
+
+ // ----- Look for options that request a call-back
+ case PCLZIP_CB_PRE_EXTRACT :
+ case PCLZIP_CB_POST_EXTRACT :
+ case PCLZIP_CB_PRE_ADD :
+ case PCLZIP_CB_POST_ADD :
+ /* for futur use
+ case PCLZIP_CB_PRE_DELETE :
+ case PCLZIP_CB_POST_DELETE :
+ case PCLZIP_CB_PRE_LIST :
+ case PCLZIP_CB_POST_LIST :
+ */
+ // ----- Check the number of parameters
+ if (($i+1) >= $p_size) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Get the value
+ $v_function_name = $p_options_list[$i+1];
+
+ // ----- Check that the value is a valid existing function
+ if (!function_exists($v_function_name)) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Set the attribute
+ $v_result_list[$p_options_list[$i]] = $v_function_name;
+ $i++;
+ break;
+
+ default :
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
+ "Unknown parameter '"
+ .$p_options_list[$i]."'");
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Next options
+ $i++;
+ }
+
+ // ----- Look for mandatory options
+ if ($v_requested_options !== false) {
+ for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
+ // ----- Look for mandatory option
+ if ($v_requested_options[$key] == 'mandatory') {
+ // ----- Look if present
+ if (!isset($v_result_list[$key])) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+ }
+ }
+ }
+
+ // ----- Look for default values
+ if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
+
+ }
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privOptionDefaultThreshold()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privOptionDefaultThreshold(&$p_options)
+ {
+ $v_result=1;
+
+ if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
+ || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) {
+ return $v_result;
+ }
+
+ // ----- Get 'memory_limit' configuration value
+ $v_memory_limit = ini_get('memory_limit');
+ $v_memory_limit = trim($v_memory_limit);
+ $last = strtolower(substr($v_memory_limit, -1));
+ $v_memory_limit = intval($v_memory_limit);
+
+ if($last == 'g')
+ //$v_memory_limit = $v_memory_limit*1024*1024*1024;
+ $v_memory_limit = $v_memory_limit*1073741824;
+ if($last == 'm')
+ //$v_memory_limit = $v_memory_limit*1024*1024;
+ $v_memory_limit = $v_memory_limit*1048576;
+ if($last == 'k')
+ $v_memory_limit = $v_memory_limit*1024;
+
+ $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit*PCLZIP_TEMPORARY_FILE_RATIO);
+
+
+ // ----- Sanity check : No threshold if value lower than 1M
+ if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) {
+ unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]);
+ }
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privFileDescrParseAtt()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // 1 on success.
+ // 0 on failure.
+ // --------------------------------------------------------------------------------
+ function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false)
+ {
+ $v_result=1;
+
+ // ----- For each file in the list check the attributes
+ foreach ($p_file_list as $v_key => $v_value) {
+
+ // ----- Check if the option is supported
+ if (!isset($v_requested_options[$v_key])) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file");
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Look for attribute
+ switch ($v_key) {
+ case PCLZIP_ATT_FILE_NAME :
+ if (!is_string($v_value)) {
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
+ return PclZip::errorCode();
+ }
+
+ $p_filedescr['filename'] = PclZipUtilPathReduction($v_value);
+
+ if ($p_filedescr['filename'] == '') {
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'");
+ return PclZip::errorCode();
+ }
+
+ break;
+
+ case PCLZIP_ATT_FILE_NEW_SHORT_NAME :
+ if (!is_string($v_value)) {
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
+ return PclZip::errorCode();
+ }
+
+ $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value);
+
+ if ($p_filedescr['new_short_name'] == '') {
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'");
+ return PclZip::errorCode();
+ }
+ break;
+
+ case PCLZIP_ATT_FILE_NEW_FULL_NAME :
+ if (!is_string($v_value)) {
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
+ return PclZip::errorCode();
+ }
+
+ $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value);
+
+ if ($p_filedescr['new_full_name'] == '') {
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'");
+ return PclZip::errorCode();
+ }
+ break;
+
+ // ----- Look for options that takes a string
+ case PCLZIP_ATT_FILE_COMMENT :
+ if (!is_string($v_value)) {
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
+ return PclZip::errorCode();
+ }
+
+ $p_filedescr['comment'] = $v_value;
+ break;
+
+ case PCLZIP_ATT_FILE_MTIME :
+ if (!is_integer($v_value)) {
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'");
+ return PclZip::errorCode();
+ }
+
+ $p_filedescr['mtime'] = $v_value;
+ break;
+
+ case PCLZIP_ATT_FILE_CONTENT :
+ $p_filedescr['content'] = $v_value;
+ break;
+
+ default :
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
+ "Unknown parameter '".$v_key."'");
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Look for mandatory options
+ if ($v_requested_options !== false) {
+ for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
+ // ----- Look for mandatory option
+ if ($v_requested_options[$key] == 'mandatory') {
+ // ----- Look if present
+ if (!isset($p_file_list[$key])) {
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
+ return PclZip::errorCode();
+ }
+ }
+ }
+ }
+
+ // end foreach
+ }
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privFileDescrExpand()
+ // Description :
+ // This method look for each item of the list to see if its a file, a folder
+ // or a string to be added as file. For any other type of files (link, other)
+ // just ignore the item.
+ // Then prepare the information that will be stored for that file.
+ // When its a folder, expand the folder with all the files that are in that
+ // folder (recursively).
+ // Parameters :
+ // Return Values :
+ // 1 on success.
+ // 0 on failure.
+ // --------------------------------------------------------------------------------
+ function privFileDescrExpand(&$p_filedescr_list, &$p_options)
+ {
+ $v_result=1;
+
+ // ----- Create a result list
+ $v_result_list = array();
+
+ // ----- Look each entry
+ for ($i=0; $iprivCalculateStoredFilename($v_descr, $p_options);
+
+ // ----- Add the descriptor in result list
+ $v_result_list[sizeof($v_result_list)] = $v_descr;
+
+ // ----- Look for folder
+ if ($v_descr['type'] == 'folder') {
+ // ----- List of items in folder
+ $v_dirlist_descr = array();
+ $v_dirlist_nb = 0;
+ if ($v_folder_handler = @opendir($v_descr['filename'])) {
+ while (($v_item_handler = @readdir($v_folder_handler)) !== false) {
+
+ // ----- Skip '.' and '..'
+ if (($v_item_handler == '.') || ($v_item_handler == '..')) {
+ continue;
+ }
+
+ // ----- Compose the full filename
+ $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler;
+
+ // ----- Look for different stored filename
+ // Because the name of the folder was changed, the name of the
+ // files/sub-folders also change
+ if (($v_descr['stored_filename'] != $v_descr['filename'])
+ && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) {
+ if ($v_descr['stored_filename'] != '') {
+ $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler;
+ }
+ else {
+ $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler;
+ }
+ }
+
+ $v_dirlist_nb++;
+ }
+
+ @closedir($v_folder_handler);
+ }
+ else {
+ // TBC : unable to open folder in read mode
+ }
+
+ // ----- Expand each element of the list
+ if ($v_dirlist_nb != 0) {
+ // ----- Expand
+ if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) {
+ return $v_result;
+ }
+
+ // ----- Concat the resulting list
+ $v_result_list = array_merge($v_result_list, $v_dirlist_descr);
+ }
+ else {
+ }
+
+ // ----- Free local array
+ unset($v_dirlist_descr);
+ }
+ }
+
+ // ----- Get the result list
+ $p_filedescr_list = $v_result_list;
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privCreate()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privCreate($p_filedescr_list, &$p_result_list, &$p_options)
+ {
+ $v_result=1;
+ $v_list_detail = array();
+
+ // ----- Magic quotes trick
+ $this->privDisableMagicQuotes();
+
+ // ----- Open the file in write mode
+ if (($v_result = $this->privOpenFd('wb')) != 1)
+ {
+ // ----- Return
+ return $v_result;
+ }
+
+ // ----- Add the list of files
+ $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options);
+
+ // ----- Close
+ $this->privCloseFd();
+
+ // ----- Magic quotes trick
+ $this->privSwapBackMagicQuotes();
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privAdd()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privAdd($p_filedescr_list, &$p_result_list, &$p_options)
+ {
+ $v_result=1;
+ $v_list_detail = array();
+
+ // ----- Look if the archive exists or is empty
+ if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0))
+ {
+
+ // ----- Do a create
+ $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options);
+
+ // ----- Return
+ return $v_result;
+ }
+ // ----- Magic quotes trick
+ $this->privDisableMagicQuotes();
+
+ // ----- Open the zip file
+ if (($v_result=$this->privOpenFd('rb')) != 1)
+ {
+ // ----- Magic quotes trick
+ $this->privSwapBackMagicQuotes();
+
+ // ----- Return
+ return $v_result;
+ }
+
+ // ----- Read the central directory informations
+ $v_central_dir = array();
+ if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
+ {
+ $this->privCloseFd();
+ $this->privSwapBackMagicQuotes();
+ return $v_result;
+ }
+
+ // ----- Go to beginning of File
+ @rewind($this->zip_fd);
+
+ // ----- Creates a temporay file
+ $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
+
+ // ----- Open the temporary file in write mode
+ if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
+ {
+ $this->privCloseFd();
+ $this->privSwapBackMagicQuotes();
+
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Copy the files from the archive to the temporary file
+ // TBC : Here I should better append the file and go back to erase the central dir
+ $v_size = $v_central_dir['offset'];
+ while ($v_size != 0)
+ {
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+ $v_buffer = fread($this->zip_fd, $v_read_size);
+ @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
+ $v_size -= $v_read_size;
+ }
+
+ // ----- Swap the file descriptor
+ // Here is a trick : I swap the temporary fd with the zip fd, in order to use
+ // the following methods on the temporary fil and not the real archive
+ $v_swap = $this->zip_fd;
+ $this->zip_fd = $v_zip_temp_fd;
+ $v_zip_temp_fd = $v_swap;
+
+ // ----- Add the files
+ $v_header_list = array();
+ if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
+ {
+ fclose($v_zip_temp_fd);
+ $this->privCloseFd();
+ @unlink($v_zip_temp_name);
+ $this->privSwapBackMagicQuotes();
+
+ // ----- Return
+ return $v_result;
+ }
+
+ // ----- Store the offset of the central dir
+ $v_offset = @ftell($this->zip_fd);
+
+ // ----- Copy the block of file headers from the old archive
+ $v_size = $v_central_dir['size'];
+ while ($v_size != 0)
+ {
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+ $v_buffer = @fread($v_zip_temp_fd, $v_read_size);
+ @fwrite($this->zip_fd, $v_buffer, $v_read_size);
+ $v_size -= $v_read_size;
+ }
+
+ // ----- Create the Central Dir files header
+ for ($i=0, $v_count=0; $iprivWriteCentralFileHeader($v_header_list[$i])) != 1) {
+ fclose($v_zip_temp_fd);
+ $this->privCloseFd();
+ @unlink($v_zip_temp_name);
+ $this->privSwapBackMagicQuotes();
+
+ // ----- Return
+ return $v_result;
+ }
+ $v_count++;
+ }
+
+ // ----- Transform the header to a 'usable' info
+ $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
+ }
+
+ // ----- Zip file comment
+ $v_comment = $v_central_dir['comment'];
+ if (isset($p_options[PCLZIP_OPT_COMMENT])) {
+ $v_comment = $p_options[PCLZIP_OPT_COMMENT];
+ }
+ if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) {
+ $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT];
+ }
+ if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) {
+ $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment;
+ }
+
+ // ----- Calculate the size of the central header
+ $v_size = @ftell($this->zip_fd)-$v_offset;
+
+ // ----- Create the central dir footer
+ if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1)
+ {
+ // ----- Reset the file list
+ unset($v_header_list);
+ $this->privSwapBackMagicQuotes();
+
+ // ----- Return
+ return $v_result;
+ }
+
+ // ----- Swap back the file descriptor
+ $v_swap = $this->zip_fd;
+ $this->zip_fd = $v_zip_temp_fd;
+ $v_zip_temp_fd = $v_swap;
+
+ // ----- Close
+ $this->privCloseFd();
+
+ // ----- Close the temporary file
+ @fclose($v_zip_temp_fd);
+
+ // ----- Magic quotes trick
+ $this->privSwapBackMagicQuotes();
+
+ // ----- Delete the zip file
+ // TBC : I should test the result ...
+ @unlink($this->zipname);
+
+ // ----- Rename the temporary file
+ // TBC : I should test the result ...
+ //@rename($v_zip_temp_name, $this->zipname);
+ PclZipUtilRename($v_zip_temp_name, $this->zipname);
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privOpenFd()
+ // Description :
+ // Parameters :
+ // --------------------------------------------------------------------------------
+ function privOpenFd($p_mode)
+ {
+ $v_result=1;
+
+ // ----- Look if already open
+ if ($this->zip_fd != 0)
+ {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open');
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Open the zip file
+ if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0)
+ {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode');
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privCloseFd()
+ // Description :
+ // Parameters :
+ // --------------------------------------------------------------------------------
+ function privCloseFd()
+ {
+ $v_result=1;
+
+ if ($this->zip_fd != 0)
+ @fclose($this->zip_fd);
+ $this->zip_fd = 0;
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privAddList()
+ // Description :
+ // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is
+ // different from the real path of the file. This is usefull if you want to have PclTar
+ // running in any directory, and memorize relative path from an other directory.
+ // Parameters :
+ // $p_list : An array containing the file or directory names to add in the tar
+ // $p_result_list : list of added files with their properties (specially the status field)
+ // $p_add_dir : Path to add in the filename path archived
+ // $p_remove_dir : Path to remove in the filename path archived
+ // Return Values :
+ // --------------------------------------------------------------------------------
+// function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options)
+ function privAddList($p_filedescr_list, &$p_result_list, &$p_options)
+ {
+ $v_result=1;
+
+ // ----- Add the files
+ $v_header_list = array();
+ if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
+ {
+ // ----- Return
+ return $v_result;
+ }
+
+ // ----- Store the offset of the central dir
+ $v_offset = @ftell($this->zip_fd);
+
+ // ----- Create the Central Dir files header
+ for ($i=0,$v_count=0; $iprivWriteCentralFileHeader($v_header_list[$i])) != 1) {
+ // ----- Return
+ return $v_result;
+ }
+ $v_count++;
+ }
+
+ // ----- Transform the header to a 'usable' info
+ $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
+ }
+
+ // ----- Zip file comment
+ $v_comment = '';
+ if (isset($p_options[PCLZIP_OPT_COMMENT])) {
+ $v_comment = $p_options[PCLZIP_OPT_COMMENT];
+ }
+
+ // ----- Calculate the size of the central header
+ $v_size = @ftell($this->zip_fd)-$v_offset;
+
+ // ----- Create the central dir footer
+ if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1)
+ {
+ // ----- Reset the file list
+ unset($v_header_list);
+
+ // ----- Return
+ return $v_result;
+ }
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privAddFileList()
+ // Description :
+ // Parameters :
+ // $p_filedescr_list : An array containing the file description
+ // or directory names to add in the zip
+ // $p_result_list : list of added files with their properties (specially the status field)
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options)
+ {
+ $v_result=1;
+ $v_header = array();
+
+ // ----- Recuperate the current number of elt in list
+ $v_nb = sizeof($p_result_list);
+
+ // ----- Loop on the files
+ for ($j=0; ($jprivAddFile($p_filedescr_list[$j], $v_header,
+ $p_options);
+ if ($v_result != 1) {
+ return $v_result;
+ }
+
+ // ----- Store the file infos
+ $p_result_list[$v_nb++] = $v_header;
+ }
+ }
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privAddFile()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privAddFile($p_filedescr, &$p_header, &$p_options)
+ {
+ $v_result=1;
+
+ // ----- Working variable
+ $p_filename = $p_filedescr['filename'];
+
+ // TBC : Already done in the fileAtt check ... ?
+ if ($p_filename == "") {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)");
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Look for a stored different filename
+ /* TBC : Removed
+ if (isset($p_filedescr['stored_filename'])) {
+ $v_stored_filename = $p_filedescr['stored_filename'];
+ }
+ else {
+ $v_stored_filename = $p_filedescr['stored_filename'];
+ }
+ */
+
+ // ----- Set the file properties
+ clearstatcache();
+ $p_header['version'] = 20;
+ $p_header['version_extracted'] = 10;
+ $p_header['flag'] = 0;
+ $p_header['compression'] = 0;
+ $p_header['crc'] = 0;
+ $p_header['compressed_size'] = 0;
+ $p_header['filename_len'] = strlen($p_filename);
+ $p_header['extra_len'] = 0;
+ $p_header['disk'] = 0;
+ $p_header['internal'] = 0;
+ $p_header['offset'] = 0;
+ $p_header['filename'] = $p_filename;
+// TBC : Removed $p_header['stored_filename'] = $v_stored_filename;
+ $p_header['stored_filename'] = $p_filedescr['stored_filename'];
+ $p_header['extra'] = '';
+ $p_header['status'] = 'ok';
+ $p_header['index'] = -1;
+
+ // ----- Look for regular file
+ if ($p_filedescr['type']=='file') {
+ $p_header['external'] = 0x00000000;
+ $p_header['size'] = filesize($p_filename);
+ }
+
+ // ----- Look for regular folder
+ else if ($p_filedescr['type']=='folder') {
+ $p_header['external'] = 0x00000010;
+ $p_header['mtime'] = filemtime($p_filename);
+ $p_header['size'] = filesize($p_filename);
+ }
+
+ // ----- Look for virtual file
+ else if ($p_filedescr['type'] == 'virtual_file') {
+ $p_header['external'] = 0x00000000;
+ $p_header['size'] = strlen($p_filedescr['content']);
+ }
+
+
+ // ----- Look for filetime
+ if (isset($p_filedescr['mtime'])) {
+ $p_header['mtime'] = $p_filedescr['mtime'];
+ }
+ else if ($p_filedescr['type'] == 'virtual_file') {
+ $p_header['mtime'] = time();
+ }
+ else {
+ $p_header['mtime'] = filemtime($p_filename);
+ }
+
+ // ------ Look for file comment
+ if (isset($p_filedescr['comment'])) {
+ $p_header['comment_len'] = strlen($p_filedescr['comment']);
+ $p_header['comment'] = $p_filedescr['comment'];
+ }
+ else {
+ $p_header['comment_len'] = 0;
+ $p_header['comment'] = '';
+ }
+
+ // ----- Look for pre-add callback
+ if (isset($p_options[PCLZIP_CB_PRE_ADD])) {
+
+ // ----- Generate a local information
+ $v_local_header = array();
+ $this->privConvertHeader2FileInfo($p_header, $v_local_header);
+
+ // ----- Call the callback
+ // Here I do not use call_user_func() because I need to send a reference to the
+ // header.
+// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);');
+ $v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header);
+ if ($v_result == 0) {
+ // ----- Change the file status
+ $p_header['status'] = "skipped";
+ $v_result = 1;
+ }
+
+ // ----- Update the informations
+ // Only some fields can be modified
+ if ($p_header['stored_filename'] != $v_local_header['stored_filename']) {
+ $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']);
+ }
+ }
+
+ // ----- Look for empty stored filename
+ if ($p_header['stored_filename'] == "") {
+ $p_header['status'] = "filtered";
+ }
+
+ // ----- Check the path length
+ if (strlen($p_header['stored_filename']) > 0xFF) {
+ $p_header['status'] = 'filename_too_long';
+ }
+
+ // ----- Look if no error, or file not skipped
+ if ($p_header['status'] == 'ok') {
+
+ // ----- Look for a file
+ if ($p_filedescr['type'] == 'file') {
+ // ----- Look for using temporary file to zip
+ if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF]))
+ && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])
+ || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
+ && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])) ) ) {
+ $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options);
+ if ($v_result < PCLZIP_ERR_NO_ERROR) {
+ return $v_result;
+ }
+ }
+
+ // ----- Use "in memory" zip algo
+ else {
+
+ // ----- Open the source file
+ if (($v_file = @fopen($p_filename, "rb")) == 0) {
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
+ return PclZip::errorCode();
+ }
+
+ // ----- Read the file content
+ $v_content = @fread($v_file, $p_header['size']);
+
+ // ----- Close the file
+ @fclose($v_file);
+
+ // ----- Calculate the CRC
+ $p_header['crc'] = @hash("crc32b", $v_content);
+
+ // ----- Look for no compression
+ if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
+ // ----- Set header parameters
+ $p_header['compressed_size'] = $p_header['size'];
+ $p_header['compression'] = 0;
+ }
+
+ // ----- Look for normal compression
+ else {
+ // ----- Compress the content
+ $v_content = @gzdeflate($v_content);
+
+ // ----- Set header parameters
+ $p_header['compressed_size'] = strlen($v_content);
+ $p_header['compression'] = 8;
+ }
+
+ // ----- Call the header generation
+ if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
+ @fclose($v_file);
+ return $v_result;
+ }
+
+ // ----- Write the compressed (or not) content
+ @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
+
+ }
+
+ }
+
+ // ----- Look for a virtual file (a file from string)
+ else if ($p_filedescr['type'] == 'virtual_file') {
+
+ $v_content = $p_filedescr['content'];
+
+ // ----- Calculate the CRC
+ $p_header['crc'] = @hash("crc32b", $v_content);
+
+ // ----- Look for no compression
+ if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
+ // ----- Set header parameters
+ $p_header['compressed_size'] = $p_header['size'];
+ $p_header['compression'] = 0;
+ }
+
+ // ----- Look for normal compression
+ else {
+ // ----- Compress the content
+ $v_content = @gzdeflate($v_content);
+
+ // ----- Set header parameters
+ $p_header['compressed_size'] = strlen($v_content);
+ $p_header['compression'] = 8;
+ }
+
+ // ----- Call the header generation
+ if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
+ @fclose($v_file);
+ return $v_result;
+ }
+
+ // ----- Write the compressed (or not) content
+ @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
+ }
+
+ // ----- Look for a directory
+ else if ($p_filedescr['type'] == 'folder') {
+ // ----- Look for directory last '/'
+ if (@substr($p_header['stored_filename'], -1) != '/') {
+ $p_header['stored_filename'] .= '/';
+ }
+
+ // ----- Set the file properties
+ $p_header['size'] = 0;
+ //$p_header['external'] = 0x41FF0010; // Value for a folder : to be checked
+ $p_header['external'] = 0x00000010; // Value for a folder : to be checked
+
+ // ----- Call the header generation
+ if (($v_result = $this->privWriteFileHeader($p_header)) != 1)
+ {
+ return $v_result;
+ }
+ }
+ }
+
+ // ----- Look for post-add callback
+ if (isset($p_options[PCLZIP_CB_POST_ADD])) {
+
+ // ----- Generate a local information
+ $v_local_header = array();
+ $this->privConvertHeader2FileInfo($p_header, $v_local_header);
+
+ // ----- Call the callback
+ // Here I do not use call_user_func() because I need to send a reference to the
+ // header.
+// eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);');
+ $v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header);
+ if ($v_result == 0) {
+ // ----- Ignored
+ $v_result = 1;
+ }
+
+ // ----- Update the informations
+ // Nothing can be modified
+ }
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privAddFileUsingTempFile()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options)
+ {
+ $v_result=PCLZIP_ERR_NO_ERROR;
+
+ // ----- Working variable
+ $p_filename = $p_filedescr['filename'];
+
+
+ // ----- Open the source file
+ if (($v_file = @fopen($p_filename, "rb")) == 0) {
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
+ return PclZip::errorCode();
+ }
+
+ // ----- Creates a compressed temporary file
+ $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';
+ if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) {
+ fclose($v_file);
+ PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode');
+ return PclZip::errorCode();
+ }
+
+ // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
+ $v_size = filesize($p_filename);
+ while ($v_size != 0) {
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+ $v_buffer = @fread($v_file, $v_read_size);
+ //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
+ @gzputs($v_file_compressed, $v_buffer, $v_read_size);
+ $v_size -= $v_read_size;
+ }
+
+ // ----- Close the file
+ @fclose($v_file);
+ @gzclose($v_file_compressed);
+
+ // ----- Check the minimum file size
+ if (filesize($v_gzip_temp_name) < 18) {
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \''.$v_gzip_temp_name.'\' has invalid filesize - should be minimum 18 bytes');
+ return PclZip::errorCode();
+ }
+
+ // ----- Extract the compressed attributes
+ if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) {
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
+ return PclZip::errorCode();
+ }
+
+ // ----- Read the gzip file header
+ $v_binary_data = @fread($v_file_compressed, 10);
+ $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data);
+
+ // ----- Check some parameters
+ $v_data_header['os'] = bin2hex($v_data_header['os']);
+
+ // ----- Read the gzip file footer
+ @fseek($v_file_compressed, filesize($v_gzip_temp_name)-8);
+ $v_binary_data = @fread($v_file_compressed, 8);
+ $v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data);
+
+ // ----- Set the attributes
+ $p_header['compression'] = ord($v_data_header['cm']);
+ //$p_header['mtime'] = $v_data_header['mtime'];
+ $p_header['crc'] = $v_data_footer['crc'];
+ $p_header['compressed_size'] = filesize($v_gzip_temp_name)-18;
+
+ // ----- Close the file
+ @fclose($v_file_compressed);
+
+ // ----- Call the header generation
+ if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
+ return $v_result;
+ }
+
+ // ----- Add the compressed data
+ if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0)
+ {
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
+ return PclZip::errorCode();
+ }
+
+ // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
+ fseek($v_file_compressed, 10);
+ $v_size = $p_header['compressed_size'];
+ while ($v_size != 0)
+ {
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+ $v_buffer = @fread($v_file_compressed, $v_read_size);
+ //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
+ @fwrite($this->zip_fd, $v_buffer, $v_read_size);
+ $v_size -= $v_read_size;
+ }
+
+ // ----- Close the file
+ @fclose($v_file_compressed);
+
+ // ----- Unlink the temporary file
+ @unlink($v_gzip_temp_name);
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privCalculateStoredFilename()
+ // Description :
+ // Based on file descriptor properties and global options, this method
+ // calculate the filename that will be stored in the archive.
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privCalculateStoredFilename(&$p_filedescr, &$p_options)
+ {
+ $v_result=1;
+
+ // ----- Working variables
+ $p_filename = $p_filedescr['filename'];
+ if (isset($p_options[PCLZIP_OPT_ADD_PATH])) {
+ $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH];
+ }
+ else {
+ $p_add_dir = '';
+ }
+ if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) {
+ $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH];
+ }
+ else {
+ $p_remove_dir = '';
+ }
+ if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
+ $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH];
+ }
+ else {
+ $p_remove_all_dir = 0;
+ }
+
+
+ // ----- Look for full name change
+ if (isset($p_filedescr['new_full_name'])) {
+ // ----- Remove drive letter if any
+ $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']);
+ }
+
+ // ----- Look for path and/or short name change
+ else {
+
+ // ----- Look for short name change
+ // Its when we cahnge just the filename but not the path
+ if (isset($p_filedescr['new_short_name'])) {
+ $v_path_info = pathinfo($p_filename);
+ $v_dir = '';
+ if ($v_path_info['dirname'] != '') {
+ $v_dir = $v_path_info['dirname'].'/';
+ }
+ $v_stored_filename = $v_dir.$p_filedescr['new_short_name'];
+ }
+ else {
+ // ----- Calculate the stored filename
+ $v_stored_filename = $p_filename;
+ }
+
+ // ----- Look for all path to remove
+ if ($p_remove_all_dir) {
+ $v_stored_filename = basename($p_filename);
+ }
+ // ----- Look for partial path remove
+ else if ($p_remove_dir != "") {
+ if (substr($p_remove_dir, -1) != '/')
+ $p_remove_dir .= "/";
+
+ if ( (substr($p_filename, 0, 2) == "./")
+ || (substr($p_remove_dir, 0, 2) == "./")) {
+
+ if ( (substr($p_filename, 0, 2) == "./")
+ && (substr($p_remove_dir, 0, 2) != "./")) {
+ $p_remove_dir = "./".$p_remove_dir;
+ }
+ if ( (substr($p_filename, 0, 2) != "./")
+ && (substr($p_remove_dir, 0, 2) == "./")) {
+ $p_remove_dir = substr($p_remove_dir, 2);
+ }
+ }
+
+ $v_compare = PclZipUtilPathInclusion($p_remove_dir,
+ $v_stored_filename);
+ if ($v_compare > 0) {
+ if ($v_compare == 2) {
+ $v_stored_filename = "";
+ }
+ else {
+ $v_stored_filename = substr($v_stored_filename,
+ strlen($p_remove_dir));
+ }
+ }
+ }
+
+ // ----- Remove drive letter if any
+ $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename);
+
+ // ----- Look for path to add
+ if ($p_add_dir != "") {
+ if (substr($p_add_dir, -1) == "/")
+ $v_stored_filename = $p_add_dir.$v_stored_filename;
+ else
+ $v_stored_filename = $p_add_dir."/".$v_stored_filename;
+ }
+ }
+
+ // ----- Filename (reduce the path of stored name)
+ $v_stored_filename = PclZipUtilPathReduction($v_stored_filename);
+ $p_filedescr['stored_filename'] = $v_stored_filename;
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privWriteFileHeader()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privWriteFileHeader(&$p_header)
+ {
+ $v_result=1;
+
+ // ----- Store the offset position of the file
+ $p_header['offset'] = ftell($this->zip_fd);
+
+ // ----- Transform UNIX mtime to DOS format mdate/mtime
+ $v_date = getdate($p_header['mtime']);
+ $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
+ $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
+
+ // ----- Packed data
+ $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50,
+ $p_header['version_extracted'], $p_header['flag'],
+ $p_header['compression'], $v_mtime, $v_mdate,
+ $p_header['crc'], $p_header['compressed_size'],
+ $p_header['size'],
+ strlen($p_header['stored_filename']),
+ $p_header['extra_len']);
+
+ // ----- Write the first 148 bytes of the header in the archive
+ fputs($this->zip_fd, $v_binary_data, 30);
+
+ // ----- Write the variable fields
+ if (strlen($p_header['stored_filename']) != 0)
+ {
+ fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
+ }
+ if ($p_header['extra_len'] != 0)
+ {
+ fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
+ }
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privWriteCentralFileHeader()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privWriteCentralFileHeader(&$p_header)
+ {
+ $v_result=1;
+
+ // TBC
+ //for(reset($p_header); $key = key($p_header); next($p_header)) {
+ //}
+
+ // ----- Transform UNIX mtime to DOS format mdate/mtime
+ $v_date = getdate($p_header['mtime']);
+ $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
+ $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
+
+
+ // ----- Packed data
+ $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50,
+ $p_header['version'], $p_header['version_extracted'],
+ $p_header['flag'], $p_header['compression'],
+ $v_mtime, $v_mdate, $p_header['crc'],
+ $p_header['compressed_size'], $p_header['size'],
+ strlen($p_header['stored_filename']),
+ $p_header['extra_len'], $p_header['comment_len'],
+ $p_header['disk'], $p_header['internal'],
+ $p_header['external'], $p_header['offset']);
+
+ // ----- Write the 42 bytes of the header in the zip file
+ fputs($this->zip_fd, $v_binary_data, 46);
+
+ // ----- Write the variable fields
+ if (strlen($p_header['stored_filename']) != 0)
+ {
+ fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
+ }
+ if ($p_header['extra_len'] != 0)
+ {
+ fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
+ }
+ if ($p_header['comment_len'] != 0)
+ {
+ fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']);
+ }
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privWriteCentralHeader()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment)
+ {
+ $v_result=1;
+
+ // ----- Packed data
+ $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries,
+ $p_nb_entries, $p_size,
+ $p_offset, strlen($p_comment));
+
+ // ----- Write the 22 bytes of the header in the zip file
+ fputs($this->zip_fd, $v_binary_data, 22);
+
+ // ----- Write the variable fields
+ if (strlen($p_comment) != 0)
+ {
+ fputs($this->zip_fd, $p_comment, strlen($p_comment));
+ }
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privList()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privList(&$p_list)
+ {
+ $v_result=1;
+
+ // ----- Magic quotes trick
+ $this->privDisableMagicQuotes();
+
+ // ----- Open the zip file
+ if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
+ {
+ // ----- Magic quotes trick
+ $this->privSwapBackMagicQuotes();
+
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Read the central directory informations
+ $v_central_dir = array();
+ if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
+ {
+ $this->privSwapBackMagicQuotes();
+ return $v_result;
+ }
+
+ // ----- Go to beginning of Central Dir
+ @rewind($this->zip_fd);
+ if (@fseek($this->zip_fd, $v_central_dir['offset']))
+ {
+ $this->privSwapBackMagicQuotes();
+
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Read each entry
+ for ($i=0; $i<$v_central_dir['entries']; $i++)
+ {
+ // ----- Read the file header
+ if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
+ {
+ $this->privSwapBackMagicQuotes();
+ return $v_result;
+ }
+ $v_header['index'] = $i;
+
+ // ----- Get the only interesting attributes
+ $this->privConvertHeader2FileInfo($v_header, $p_list[$i]);
+ unset($v_header);
+ }
+
+ // ----- Close the zip file
+ $this->privCloseFd();
+
+ // ----- Magic quotes trick
+ $this->privSwapBackMagicQuotes();
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privConvertHeader2FileInfo()
+ // Description :
+ // This function takes the file informations from the central directory
+ // entries and extract the interesting parameters that will be given back.
+ // The resulting file infos are set in the array $p_info
+ // $p_info['filename'] : Filename with full path. Given by user (add),
+ // extracted in the filesystem (extract).
+ // $p_info['stored_filename'] : Stored filename in the archive.
+ // $p_info['size'] = Size of the file.
+ // $p_info['compressed_size'] = Compressed size of the file.
+ // $p_info['mtime'] = Last modification date of the file.
+ // $p_info['comment'] = Comment associated with the file.
+ // $p_info['folder'] = true/false : indicates if the entry is a folder or not.
+ // $p_info['status'] = status of the action on the file.
+ // $p_info['crc'] = CRC of the file content.
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privConvertHeader2FileInfo($p_header, &$p_info)
+ {
+ $v_result=1;
+
+ // ----- Get the interesting attributes
+ $v_temp_path = PclZipUtilPathReduction($p_header['filename']);
+ $p_info['filename'] = $v_temp_path;
+ $v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']);
+ $p_info['stored_filename'] = $v_temp_path;
+ $p_info['size'] = $p_header['size'];
+ $p_info['compressed_size'] = $p_header['compressed_size'];
+ $p_info['mtime'] = $p_header['mtime'];
+ $p_info['comment'] = $p_header['comment'];
+ $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010);
+ $p_info['index'] = $p_header['index'];
+ $p_info['status'] = $p_header['status'];
+ $p_info['crc'] = $p_header['crc'];
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privExtractByRule()
+ // Description :
+ // Extract a file or directory depending of rules (by index, by name, ...)
+ // Parameters :
+ // $p_file_list : An array where will be placed the properties of each
+ // extracted file
+ // $p_path : Path to add while writing the extracted files
+ // $p_remove_path : Path to remove (from the file memorized path) while writing the
+ // extracted files. If the path does not match the file path,
+ // the file is extracted with its memorized path.
+ // $p_remove_path does not apply to 'list' mode.
+ // $p_path and $p_remove_path are commulative.
+ // Return Values :
+ // 1 on success,0 or less on error (see error code list)
+ // --------------------------------------------------------------------------------
+ function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
+ {
+ $v_result=1;
+
+ // ----- Magic quotes trick
+ $this->privDisableMagicQuotes();
+
+ // ----- Check the path
+ if ( ($p_path == "")
+ || ( (substr($p_path, 0, 1) != "/")
+ && (substr($p_path, 0, 3) != "../")
+ && (substr($p_path,1,2)!=":/")))
+ $p_path = "./".$p_path;
+
+ // ----- Reduce the path last (and duplicated) '/'
+ if (($p_path != "./") && ($p_path != "/"))
+ {
+ // ----- Look for the path end '/'
+ while (substr($p_path, -1) == "/")
+ {
+ $p_path = substr($p_path, 0, strlen($p_path)-1);
+ }
+ }
+
+ // ----- Look for path to remove format (should end by /)
+ if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/'))
+ {
+ $p_remove_path .= '/';
+ }
+ $p_remove_path_size = strlen($p_remove_path);
+
+ // ----- Open the zip file
+ if (($v_result = $this->privOpenFd('rb')) != 1)
+ {
+ $this->privSwapBackMagicQuotes();
+ return $v_result;
+ }
+
+ // ----- Read the central directory informations
+ $v_central_dir = array();
+ if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
+ {
+ // ----- Close the zip file
+ $this->privCloseFd();
+ $this->privSwapBackMagicQuotes();
+
+ return $v_result;
+ }
+
+ // ----- Start at beginning of Central Dir
+ $v_pos_entry = $v_central_dir['offset'];
+
+ // ----- Read each entry
+ $j_start = 0;
+ for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
+ {
+
+ // ----- Read next Central dir entry
+ @rewind($this->zip_fd);
+ if (@fseek($this->zip_fd, $v_pos_entry))
+ {
+ // ----- Close the zip file
+ $this->privCloseFd();
+ $this->privSwapBackMagicQuotes();
+
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Read the file header
+ $v_header = array();
+ if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
+ {
+ // ----- Close the zip file
+ $this->privCloseFd();
+ $this->privSwapBackMagicQuotes();
+
+ return $v_result;
+ }
+
+ // ----- Store the index
+ $v_header['index'] = $i;
+
+ // ----- Store the file position
+ $v_pos_entry = ftell($this->zip_fd);
+
+ // ----- Look for the specific extract rules
+ $v_extract = false;
+
+ // ----- Look for extract by name rule
+ if ( (isset($p_options[PCLZIP_OPT_BY_NAME]))
+ && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
+
+ // ----- Look if the filename is in the list
+ for ($j=0; ($j strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
+ && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
+ $v_extract = true;
+ }
+ }
+ // ----- Look for a filename
+ elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
+ $v_extract = true;
+ }
+ }
+ }
+
+ // ----- Look for extract by ereg rule
+ // ereg() is deprecated with PHP 5.3
+ /*
+ else if ( (isset($p_options[PCLZIP_OPT_BY_EREG]))
+ && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
+
+ if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) {
+ $v_extract = true;
+ }
+ }
+ */
+
+ // ----- Look for extract by preg rule
+ else if ( (isset($p_options[PCLZIP_OPT_BY_PREG]))
+ && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
+
+ if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) {
+ $v_extract = true;
+ }
+ }
+
+ // ----- Look for extract by index rule
+ else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX]))
+ && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
+
+ // ----- Look if the index is in the list
+ for ($j=$j_start; ($j=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
+ $v_extract = true;
+ }
+ if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
+ $j_start = $j+1;
+ }
+
+ if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
+ break;
+ }
+ }
+ }
+
+ // ----- Look for no rule, which means extract all the archive
+ else {
+ $v_extract = true;
+ }
+
+ // ----- Check compression method
+ if ( ($v_extract)
+ && ( ($v_header['compression'] != 8)
+ && ($v_header['compression'] != 0))) {
+ $v_header['status'] = 'unsupported_compression';
+
+ // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
+ if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
+ && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
+
+ $this->privSwapBackMagicQuotes();
+
+ PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION,
+ "Filename '".$v_header['stored_filename']."' is "
+ ."compressed by an unsupported compression "
+ ."method (".$v_header['compression'].") ");
+
+ return PclZip::errorCode();
+ }
+ }
+
+ // ----- Check encrypted files
+ if (($v_extract) && (($v_header['flag'] & 1) == 1)) {
+ $v_header['status'] = 'unsupported_encryption';
+
+ // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
+ if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
+ && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
+
+ $this->privSwapBackMagicQuotes();
+
+ PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION,
+ "Unsupported encryption for "
+ ." filename '".$v_header['stored_filename']
+ ."'");
+
+ return PclZip::errorCode();
+ }
+ }
+
+ // ----- Look for real extraction
+ if (($v_extract) && ($v_header['status'] != 'ok')) {
+ $v_result = $this->privConvertHeader2FileInfo($v_header,
+ $p_file_list[$v_nb_extracted++]);
+ if ($v_result != 1) {
+ $this->privCloseFd();
+ $this->privSwapBackMagicQuotes();
+ return $v_result;
+ }
+
+ $v_extract = false;
+ }
+
+ // ----- Look for real extraction
+ if ($v_extract)
+ {
+
+ // ----- Go to the file position
+ @rewind($this->zip_fd);
+ if (@fseek($this->zip_fd, $v_header['offset']))
+ {
+ // ----- Close the zip file
+ $this->privCloseFd();
+
+ $this->privSwapBackMagicQuotes();
+
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Look for extraction as string
+ if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) {
+
+ $v_string = '';
+
+ // ----- Extracting the file
+ $v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options);
+ if ($v_result1 < 1) {
+ $this->privCloseFd();
+ $this->privSwapBackMagicQuotes();
+ return $v_result1;
+ }
+
+ // ----- Get the only interesting attributes
+ if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1)
+ {
+ // ----- Close the zip file
+ $this->privCloseFd();
+ $this->privSwapBackMagicQuotes();
+
+ return $v_result;
+ }
+
+ // ----- Set the file content
+ $p_file_list[$v_nb_extracted]['content'] = $v_string;
+
+ // ----- Next extracted file
+ $v_nb_extracted++;
+
+ // ----- Look for user callback abort
+ if ($v_result1 == 2) {
+ break;
+ }
+ }
+ // ----- Look for extraction in standard output
+ elseif ( (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT]))
+ && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) {
+ // ----- Extracting the file in standard output
+ $v_result1 = $this->privExtractFileInOutput($v_header, $p_options);
+ if ($v_result1 < 1) {
+ $this->privCloseFd();
+ $this->privSwapBackMagicQuotes();
+ return $v_result1;
+ }
+
+ // ----- Get the only interesting attributes
+ if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) {
+ $this->privCloseFd();
+ $this->privSwapBackMagicQuotes();
+ return $v_result;
+ }
+
+ // ----- Look for user callback abort
+ if ($v_result1 == 2) {
+ break;
+ }
+ }
+ // ----- Look for normal extraction
+ else {
+ // ----- Extracting the file
+ $v_result1 = $this->privExtractFile($v_header,
+ $p_path, $p_remove_path,
+ $p_remove_all_path,
+ $p_options);
+ if ($v_result1 < 1) {
+ $this->privCloseFd();
+ $this->privSwapBackMagicQuotes();
+ return $v_result1;
+ }
+
+ // ----- Get the only interesting attributes
+ if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1)
+ {
+ // ----- Close the zip file
+ $this->privCloseFd();
+ $this->privSwapBackMagicQuotes();
+
+ return $v_result;
+ }
+
+ // ----- Look for user callback abort
+ if ($v_result1 == 2) {
+ break;
+ }
+ }
+ }
+ }
+
+ // ----- Close the zip file
+ $this->privCloseFd();
+ $this->privSwapBackMagicQuotes();
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privExtractFile()
+ // Description :
+ // Parameters :
+ // Return Values :
+ //
+ // 1 : ... ?
+ // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback
+ // --------------------------------------------------------------------------------
+ function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
+ {
+ $v_result=1;
+
+ // ----- Read the file header
+ if (($v_result = $this->privReadFileHeader($v_header)) != 1)
+ {
+ // ----- Return
+ return $v_result;
+ }
+
+
+ // ----- Check that the file header is coherent with $p_entry info
+ if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
+ // TBC
+ }
+
+ // ----- Look for all path to remove
+ if ($p_remove_all_path == true) {
+ // ----- Look for folder entry that not need to be extracted
+ if (($p_entry['external']&0x00000010)==0x00000010) {
+
+ $p_entry['status'] = "filtered";
+
+ return $v_result;
+ }
+
+ // ----- Get the basename of the path
+ $p_entry['filename'] = basename($p_entry['filename']);
+ }
+
+ // ----- Look for path to remove
+ else if ($p_remove_path != "")
+ {
+ if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2)
+ {
+
+ // ----- Change the file status
+ $p_entry['status'] = "filtered";
+
+ // ----- Return
+ return $v_result;
+ }
+
+ $p_remove_path_size = strlen($p_remove_path);
+ if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path)
+ {
+
+ // ----- Remove the path
+ $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size);
+
+ }
+ }
+
+ // ----- Add the path
+ if ($p_path != '') {
+ $p_entry['filename'] = $p_path."/".$p_entry['filename'];
+ }
+
+ // ----- Check a base_dir_restriction
+ if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) {
+ $v_inclusion
+ = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION],
+ $p_entry['filename']);
+ if ($v_inclusion == 0) {
+
+ PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION,
+ "Filename '".$p_entry['filename']."' is "
+ ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION");
+
+ return PclZip::errorCode();
+ }
+ }
+
+ // ----- Look for pre-extract callback
+ if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
+
+ // ----- Generate a local information
+ $v_local_header = array();
+ $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
+
+ // ----- Call the callback
+ // Here I do not use call_user_func() because I need to send a reference to the
+ // header.
+// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
+ $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
+ if ($v_result == 0) {
+ // ----- Change the file status
+ $p_entry['status'] = "skipped";
+ $v_result = 1;
+ }
+
+ // ----- Look for abort result
+ if ($v_result == 2) {
+ // ----- This status is internal and will be changed in 'skipped'
+ $p_entry['status'] = "aborted";
+ $v_result = PCLZIP_ERR_USER_ABORTED;
+ }
+
+ // ----- Update the informations
+ // Only some fields can be modified
+ $p_entry['filename'] = $v_local_header['filename'];
+ }
+
+
+ // ----- Look if extraction should be done
+ if ($p_entry['status'] == 'ok') {
+
+ // ----- Look for specific actions while the file exist
+ if (file_exists($p_entry['filename']))
+ {
+
+ // ----- Look if file is a directory
+ if (is_dir($p_entry['filename']))
+ {
+
+ // ----- Change the file status
+ $p_entry['status'] = "already_a_directory";
+
+ // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
+ // For historical reason first PclZip implementation does not stop
+ // when this kind of error occurs.
+ if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
+ && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
+
+ PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY,
+ "Filename '".$p_entry['filename']."' is "
+ ."already used by an existing directory");
+
+ return PclZip::errorCode();
+ }
+ }
+ // ----- Look if file is write protected
+ else if (!is_writeable($p_entry['filename']))
+ {
+
+ // ----- Change the file status
+ $p_entry['status'] = "write_protected";
+
+ // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
+ // For historical reason first PclZip implementation does not stop
+ // when this kind of error occurs.
+ if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
+ && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
+
+ PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
+ "Filename '".$p_entry['filename']."' exists "
+ ."and is write protected");
+
+ return PclZip::errorCode();
+ }
+ }
+
+ // ----- Look if the extracted file is older
+ else if (filemtime($p_entry['filename']) > $p_entry['mtime'])
+ {
+ // ----- Change the file status
+ if ( (isset($p_options[PCLZIP_OPT_REPLACE_NEWER]))
+ && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) {
+ }
+ else {
+ $p_entry['status'] = "newer_exist";
+
+ // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
+ // For historical reason first PclZip implementation does not stop
+ // when this kind of error occurs.
+ if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
+ && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
+
+ PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
+ "Newer version of '".$p_entry['filename']."' exists "
+ ."and option PCLZIP_OPT_REPLACE_NEWER is not selected");
+
+ return PclZip::errorCode();
+ }
+ }
+ }
+ else {
+ }
+ }
+
+ // ----- Check the directory availability and create it if necessary
+ else {
+ if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/'))
+ $v_dir_to_check = $p_entry['filename'];
+ else if (!strstr($p_entry['filename'], "/"))
+ $v_dir_to_check = "";
+ else
+ $v_dir_to_check = dirname($p_entry['filename']);
+
+ if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) {
+
+ // ----- Change the file status
+ $p_entry['status'] = "path_creation_fail";
+
+ // ----- Return
+ //return $v_result;
+ $v_result = 1;
+ }
+ }
+ }
+
+ // ----- Look if extraction should be done
+ if ($p_entry['status'] == 'ok') {
+
+ // ----- Do the extraction (if not a folder)
+ if (!(($p_entry['external']&0x00000010)==0x00000010))
+ {
+ // ----- Look for not compressed file
+ if ($p_entry['compression'] == 0) {
+
+ // ----- Opening destination file
+ if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0)
+ {
+
+ // ----- Change the file status
+ $p_entry['status'] = "write_error";
+
+ // ----- Return
+ return $v_result;
+ }
+
+
+ // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
+ $v_size = $p_entry['compressed_size'];
+ while ($v_size != 0)
+ {
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+ $v_buffer = @fread($this->zip_fd, $v_read_size);
+ /* Try to speed up the code
+ $v_binary_data = pack('a'.$v_read_size, $v_buffer);
+ @fwrite($v_dest_file, $v_binary_data, $v_read_size);
+ */
+ @fwrite($v_dest_file, $v_buffer, $v_read_size);
+ $v_size -= $v_read_size;
+ }
+
+ // ----- Closing the destination file
+ fclose($v_dest_file);
+
+ // ----- Change the file mtime
+ touch($p_entry['filename'], $p_entry['mtime']);
+
+
+ }
+ else {
+ // ----- TBC
+ // Need to be finished
+ if (($p_entry['flag'] & 1) == 1) {
+ PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \''.$p_entry['filename'].'\' is encrypted. Encrypted files are not supported.');
+ return PclZip::errorCode();
+ }
+
+
+ // ----- Look for using temporary file to unzip
+ if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF]))
+ && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])
+ || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
+ && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])) ) ) {
+ $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options);
+ if ($v_result < PCLZIP_ERR_NO_ERROR) {
+ return $v_result;
+ }
+ }
+
+ // ----- Look for extract in memory
+ else {
+
+
+ // ----- Read the compressed file in a buffer (one shot)
+ $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
+
+ // ----- Decompress the file
+ $v_file_content = @gzinflate($v_buffer);
+ unset($v_buffer);
+ if ($v_file_content === FALSE) {
+
+ // ----- Change the file status
+ // TBC
+ $p_entry['status'] = "error";
+
+ return $v_result;
+ }
+
+ // ----- Opening destination file
+ if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
+
+ // ----- Change the file status
+ $p_entry['status'] = "write_error";
+
+ return $v_result;
+ }
+
+ // ----- Write the uncompressed data
+ @fwrite($v_dest_file, $v_file_content, $p_entry['size']);
+ unset($v_file_content);
+
+ // ----- Closing the destination file
+ @fclose($v_dest_file);
+
+ }
+
+ // ----- Change the file mtime
+ @touch($p_entry['filename'], $p_entry['mtime']);
+ }
+
+ // ----- Look for chmod option
+ if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) {
+
+ // ----- Change the mode of the file
+ @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]);
+ }
+
+ }
+ }
+
+ // ----- Change abort status
+ if ($p_entry['status'] == "aborted") {
+ $p_entry['status'] = "skipped";
+ }
+
+ // ----- Look for post-extract callback
+ elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
+
+ // ----- Generate a local information
+ $v_local_header = array();
+ $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
+
+ // ----- Call the callback
+ // Here I do not use call_user_func() because I need to send a reference to the
+ // header.
+// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
+ $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
+
+ // ----- Look for abort result
+ if ($v_result == 2) {
+ $v_result = PCLZIP_ERR_USER_ABORTED;
+ }
+ }
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privExtractFileUsingTempFile()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privExtractFileUsingTempFile(&$p_entry, &$p_options)
+ {
+ $v_result=1;
+
+ // ----- Creates a temporary file
+ $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';
+ if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) {
+ fclose($v_file);
+ PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode');
+ return PclZip::errorCode();
+ }
+
+
+ // ----- Write gz file format header
+ $v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3));
+ @fwrite($v_dest_file, $v_binary_data, 10);
+
+ // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
+ $v_size = $p_entry['compressed_size'];
+ while ($v_size != 0)
+ {
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+ $v_buffer = @fread($this->zip_fd, $v_read_size);
+ //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
+ @fwrite($v_dest_file, $v_buffer, $v_read_size);
+ $v_size -= $v_read_size;
+ }
+
+ // ----- Write gz file format footer
+ $v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']);
+ @fwrite($v_dest_file, $v_binary_data, 8);
+
+ // ----- Close the temporary file
+ @fclose($v_dest_file);
+
+ // ----- Opening destination file
+ if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
+ $p_entry['status'] = "write_error";
+ return $v_result;
+ }
+
+ // ----- Open the temporary gz file
+ if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) {
+ @fclose($v_dest_file);
+ $p_entry['status'] = "read_error";
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
+ return PclZip::errorCode();
+ }
+
+
+ // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
+ $v_size = $p_entry['size'];
+ while ($v_size != 0) {
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+ $v_buffer = @gzread($v_src_file, $v_read_size);
+ //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
+ @fwrite($v_dest_file, $v_buffer, $v_read_size);
+ $v_size -= $v_read_size;
+ }
+ @fclose($v_dest_file);
+ @gzclose($v_src_file);
+
+ // ----- Delete the temporary file
+ @unlink($v_gzip_temp_name);
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privExtractFileInOutput()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privExtractFileInOutput(&$p_entry, &$p_options)
+ {
+ $v_result=1;
+
+ // ----- Read the file header
+ if (($v_result = $this->privReadFileHeader($v_header)) != 1) {
+ return $v_result;
+ }
+
+
+ // ----- Check that the file header is coherent with $p_entry info
+ if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
+ // TBC
+ }
+
+ // ----- Look for pre-extract callback
+ if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
+
+ // ----- Generate a local information
+ $v_local_header = array();
+ $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
+
+ // ----- Call the callback
+ // Here I do not use call_user_func() because I need to send a reference to the
+ // header.
+// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
+ $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
+ if ($v_result == 0) {
+ // ----- Change the file status
+ $p_entry['status'] = "skipped";
+ $v_result = 1;
+ }
+
+ // ----- Look for abort result
+ if ($v_result == 2) {
+ // ----- This status is internal and will be changed in 'skipped'
+ $p_entry['status'] = "aborted";
+ $v_result = PCLZIP_ERR_USER_ABORTED;
+ }
+
+ // ----- Update the informations
+ // Only some fields can be modified
+ $p_entry['filename'] = $v_local_header['filename'];
+ }
+
+ // ----- Trace
+
+ // ----- Look if extraction should be done
+ if ($p_entry['status'] == 'ok') {
+
+ // ----- Do the extraction (if not a folder)
+ if (!(($p_entry['external']&0x00000010)==0x00000010)) {
+ // ----- Look for not compressed file
+ if ($p_entry['compressed_size'] == $p_entry['size']) {
+
+ // ----- Read the file in a buffer (one shot)
+ $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
+
+ // ----- Send the file to the output
+ echo $v_buffer;
+ unset($v_buffer);
+ }
+ else {
+
+ // ----- Read the compressed file in a buffer (one shot)
+ $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
+
+ // ----- Decompress the file
+ $v_file_content = gzinflate($v_buffer);
+ unset($v_buffer);
+
+ // ----- Send the file to the output
+ echo $v_file_content;
+ unset($v_file_content);
+ }
+ }
+ }
+
+ // ----- Change abort status
+ if ($p_entry['status'] == "aborted") {
+ $p_entry['status'] = "skipped";
+ }
+
+ // ----- Look for post-extract callback
+ elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
+
+ // ----- Generate a local information
+ $v_local_header = array();
+ $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
+
+ // ----- Call the callback
+ // Here I do not use call_user_func() because I need to send a reference to the
+ // header.
+// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
+ $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
+
+ // ----- Look for abort result
+ if ($v_result == 2) {
+ $v_result = PCLZIP_ERR_USER_ABORTED;
+ }
+ }
+
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privExtractFileAsString()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privExtractFileAsString(&$p_entry, &$p_string, &$p_options)
+ {
+ $v_result=1;
+
+ // ----- Read the file header
+ $v_header = array();
+ if (($v_result = $this->privReadFileHeader($v_header)) != 1)
+ {
+ // ----- Return
+ return $v_result;
+ }
+
+
+ // ----- Check that the file header is coherent with $p_entry info
+ if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
+ // TBC
+ }
+
+ // ----- Look for pre-extract callback
+ if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
+
+ // ----- Generate a local information
+ $v_local_header = array();
+ $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
+
+ // ----- Call the callback
+ // Here I do not use call_user_func() because I need to send a reference to the
+ // header.
+// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
+ $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
+ if ($v_result == 0) {
+ // ----- Change the file status
+ $p_entry['status'] = "skipped";
+ $v_result = 1;
+ }
+
+ // ----- Look for abort result
+ if ($v_result == 2) {
+ // ----- This status is internal and will be changed in 'skipped'
+ $p_entry['status'] = "aborted";
+ $v_result = PCLZIP_ERR_USER_ABORTED;
+ }
+
+ // ----- Update the informations
+ // Only some fields can be modified
+ $p_entry['filename'] = $v_local_header['filename'];
+ }
+
+
+ // ----- Look if extraction should be done
+ if ($p_entry['status'] == 'ok') {
+
+ // ----- Do the extraction (if not a folder)
+ if (!(($p_entry['external']&0x00000010)==0x00000010)) {
+ // ----- Look for not compressed file
+ // if ($p_entry['compressed_size'] == $p_entry['size'])
+ if ($p_entry['compression'] == 0) {
+
+ // ----- Reading the file
+ $p_string = @fread($this->zip_fd, $p_entry['compressed_size']);
+ }
+ else {
+
+ // ----- Reading the file
+ $v_data = @fread($this->zip_fd, $p_entry['compressed_size']);
+
+ // ----- Decompress the file
+ if (($p_string = @gzinflate($v_data)) === FALSE) {
+ // TBC
+ }
+ }
+
+ // ----- Trace
+ }
+ else {
+ // TBC : error : can not extract a folder in a string
+ }
+
+ }
+
+ // ----- Change abort status
+ if ($p_entry['status'] == "aborted") {
+ $p_entry['status'] = "skipped";
+ }
+
+ // ----- Look for post-extract callback
+ elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
+
+ // ----- Generate a local information
+ $v_local_header = array();
+ $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
+
+ // ----- Swap the content to header
+ $v_local_header['content'] = $p_string;
+ $p_string = '';
+
+ // ----- Call the callback
+ // Here I do not use call_user_func() because I need to send a reference to the
+ // header.
+// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
+ $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
+
+ // ----- Swap back the content to header
+ $p_string = $v_local_header['content'];
+ unset($v_local_header['content']);
+
+ // ----- Look for abort result
+ if ($v_result == 2) {
+ $v_result = PCLZIP_ERR_USER_ABORTED;
+ }
+ }
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privReadFileHeader()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privReadFileHeader(&$p_header)
+ {
+ $v_result=1;
+
+ // ----- Read the 4 bytes signature
+ $v_binary_data = @fread($this->zip_fd, 4);
+ $v_data = unpack('Vid', $v_binary_data);
+
+ // ----- Check signature
+ if ($v_data['id'] != 0x04034b50)
+ {
+
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Read the first 42 bytes of the header
+ $v_binary_data = fread($this->zip_fd, 26);
+
+ // ----- Look for invalid block size
+ if (strlen($v_binary_data) != 26)
+ {
+ $p_header['filename'] = "";
+ $p_header['status'] = "invalid_header";
+
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Extract the values
+ $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data);
+
+ // ----- Get filename
+ $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']);
+
+ // ----- Get extra_fields
+ if ($v_data['extra_len'] != 0) {
+ $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']);
+ }
+ else {
+ $p_header['extra'] = '';
+ }
+
+ // ----- Extract properties
+ $p_header['version_extracted'] = $v_data['version'];
+ $p_header['compression'] = $v_data['compression'];
+ $p_header['size'] = $v_data['size'];
+ $p_header['compressed_size'] = $v_data['compressed_size'];
+ $p_header['crc'] = $v_data['crc'];
+ $p_header['flag'] = $v_data['flag'];
+ $p_header['filename_len'] = $v_data['filename_len'];
+
+ // ----- Recuperate date in UNIX format
+ $p_header['mdate'] = $v_data['mdate'];
+ $p_header['mtime'] = $v_data['mtime'];
+ if ($p_header['mdate'] && $p_header['mtime'])
+ {
+ // ----- Extract time
+ $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
+ $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
+ $v_seconde = ($p_header['mtime'] & 0x001F)*2;
+
+ // ----- Extract date
+ $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
+ $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
+ $v_day = $p_header['mdate'] & 0x001F;
+
+ // ----- Get UNIX date format
+ $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
+
+ }
+ else
+ {
+ $p_header['mtime'] = time();
+ }
+
+ // TBC
+ //for(reset($v_data); $key = key($v_data); next($v_data)) {
+ //}
+
+ // ----- Set the stored filename
+ $p_header['stored_filename'] = $p_header['filename'];
+
+ // ----- Set the status field
+ $p_header['status'] = "ok";
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privReadCentralFileHeader()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privReadCentralFileHeader(&$p_header)
+ {
+ $v_result=1;
+
+ // ----- Read the 4 bytes signature
+ $v_binary_data = @fread($this->zip_fd, 4);
+ $v_data = unpack('Vid', $v_binary_data);
+
+ // ----- Check signature
+ if ($v_data['id'] != 0x02014b50)
+ {
+
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Read the first 42 bytes of the header
+ $v_binary_data = fread($this->zip_fd, 42);
+
+ // ----- Look for invalid block size
+ if (strlen($v_binary_data) != 42)
+ {
+ $p_header['filename'] = "";
+ $p_header['status'] = "invalid_header";
+
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Extract the values
+ $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data);
+
+ // ----- Get filename
+ if ($p_header['filename_len'] != 0)
+ $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']);
+ else
+ $p_header['filename'] = '';
+
+ // ----- Get extra
+ if ($p_header['extra_len'] != 0)
+ $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']);
+ else
+ $p_header['extra'] = '';
+
+ // ----- Get comment
+ if ($p_header['comment_len'] != 0)
+ $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']);
+ else
+ $p_header['comment'] = '';
+
+ // ----- Extract properties
+
+ // ----- Recuperate date in UNIX format
+ //if ($p_header['mdate'] && $p_header['mtime'])
+ // TBC : bug : this was ignoring time with 0/0/0
+ if (1)
+ {
+ // ----- Extract time
+ $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
+ $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
+ $v_seconde = ($p_header['mtime'] & 0x001F)*2;
+
+ // ----- Extract date
+ $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
+ $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
+ $v_day = $p_header['mdate'] & 0x001F;
+
+ // ----- Get UNIX date format
+ $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
+
+ }
+ else
+ {
+ $p_header['mtime'] = time();
+ }
+
+ // ----- Set the stored filename
+ $p_header['stored_filename'] = $p_header['filename'];
+
+ // ----- Set default status to ok
+ $p_header['status'] = 'ok';
+
+ // ----- Look if it is a directory
+ if (substr($p_header['filename'], -1) == '/') {
+ //$p_header['external'] = 0x41FF0010;
+ $p_header['external'] = 0x00000010;
+ }
+
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privCheckFileHeaders()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // 1 on success,
+ // 0 on error;
+ // --------------------------------------------------------------------------------
+ function privCheckFileHeaders(&$p_local_header, &$p_central_header)
+ {
+ $v_result=1;
+
+ // ----- Check the static values
+ // TBC
+ if ($p_local_header['filename'] != $p_central_header['filename']) {
+ }
+ if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) {
+ }
+ if ($p_local_header['flag'] != $p_central_header['flag']) {
+ }
+ if ($p_local_header['compression'] != $p_central_header['compression']) {
+ }
+ if ($p_local_header['mtime'] != $p_central_header['mtime']) {
+ }
+ if ($p_local_header['filename_len'] != $p_central_header['filename_len']) {
+ }
+
+ // ----- Look for flag bit 3
+ if (($p_local_header['flag'] & 8) == 8) {
+ $p_local_header['size'] = $p_central_header['size'];
+ $p_local_header['compressed_size'] = $p_central_header['compressed_size'];
+ $p_local_header['crc'] = $p_central_header['crc'];
+ }
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privReadEndCentralDir()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privReadEndCentralDir(&$p_central_dir)
+ {
+ $v_result=1;
+
+ // ----- Go to the end of the zip file
+ $v_size = filesize($this->zipname);
+ @fseek($this->zip_fd, $v_size);
+ if (@ftell($this->zip_fd) != $v_size)
+ {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\'');
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- First try : look if this is an archive with no commentaries (most of the time)
+ // in this case the end of central dir is at 22 bytes of the file end
+ $v_found = 0;
+ if ($v_size > 26) {
+ @fseek($this->zip_fd, $v_size-22);
+ if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22))
+ {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Read for bytes
+ $v_binary_data = @fread($this->zip_fd, 4);
+ $v_data = @unpack('Vid', $v_binary_data);
+
+ // ----- Check signature
+ if ($v_data['id'] == 0x06054b50) {
+ $v_found = 1;
+ }
+
+ $v_pos = ftell($this->zip_fd);
+ }
+
+ // ----- Go back to the maximum possible size of the Central Dir End Record
+ if (!$v_found) {
+ $v_maximum_size = 65557; // 0xFFFF + 22;
+ if ($v_maximum_size > $v_size)
+ $v_maximum_size = $v_size;
+ @fseek($this->zip_fd, $v_size-$v_maximum_size);
+ if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size))
+ {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Read byte per byte in order to find the signature
+ $v_pos = ftell($this->zip_fd);
+ $v_bytes = 0x00000000;
+ while ($v_pos < $v_size)
+ {
+ // ----- Read a byte
+ $v_byte = @fread($this->zip_fd, 1);
+
+ // ----- Add the byte
+ //$v_bytes = ($v_bytes << 8) | Ord($v_byte);
+ // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number
+ // Otherwise on systems where we have 64bit integers the check below for the magic number will fail.
+ $v_bytes = ( ($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte);
+
+ // ----- Compare the bytes
+ if ($v_bytes == 0x504b0506)
+ {
+ $v_pos++;
+ break;
+ }
+
+ $v_pos++;
+ }
+
+ // ----- Look if not found end of central dir
+ if ($v_pos == $v_size)
+ {
+
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature");
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+ }
+
+ // ----- Read the first 18 bytes of the header
+ $v_binary_data = fread($this->zip_fd, 18);
+
+ // ----- Look for invalid block size
+ if (strlen($v_binary_data) != 18)
+ {
+
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data));
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Extract the values
+ $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);
+
+ // ----- Check the global size
+ if (($v_pos + $v_data['comment_size'] + 18) != $v_size) {
+
+ // ----- Removed in release 2.2 see readme file
+ // The check of the file size is a little too strict.
+ // Some bugs where found when a zip is encrypted/decrypted with 'crypt'.
+ // While decrypted, zip has training 0 bytes
+ if (0) {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT,
+ 'The central dir is not at the end of the archive.'
+ .' Some trailing bytes exists after the archive.');
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+ }
+
+ // ----- Get comment
+ if ($v_data['comment_size'] != 0) {
+ $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']);
+ }
+ else
+ $p_central_dir['comment'] = '';
+
+ $p_central_dir['entries'] = $v_data['entries'];
+ $p_central_dir['disk_entries'] = $v_data['disk_entries'];
+ $p_central_dir['offset'] = $v_data['offset'];
+ $p_central_dir['size'] = $v_data['size'];
+ $p_central_dir['disk'] = $v_data['disk'];
+ $p_central_dir['disk_start'] = $v_data['disk_start'];
+
+ // TBC
+ //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) {
+ //}
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privDeleteByRule()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privDeleteByRule(&$p_result_list, &$p_options)
+ {
+ $v_result=1;
+ $v_list_detail = array();
+
+ // ----- Open the zip file
+ if (($v_result=$this->privOpenFd('rb')) != 1)
+ {
+ // ----- Return
+ return $v_result;
+ }
+
+ // ----- Read the central directory informations
+ $v_central_dir = array();
+ if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
+ {
+ $this->privCloseFd();
+ return $v_result;
+ }
+
+ // ----- Go to beginning of File
+ @rewind($this->zip_fd);
+
+ // ----- Scan all the files
+ // ----- Start at beginning of Central Dir
+ $v_pos_entry = $v_central_dir['offset'];
+ @rewind($this->zip_fd);
+ if (@fseek($this->zip_fd, $v_pos_entry))
+ {
+ // ----- Close the zip file
+ $this->privCloseFd();
+
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Read each entry
+ $v_header_list = array();
+ $j_start = 0;
+ for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
+ {
+
+ // ----- Read the file header
+ $v_header_list[$v_nb_extracted] = array();
+ if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1)
+ {
+ // ----- Close the zip file
+ $this->privCloseFd();
+
+ return $v_result;
+ }
+
+
+ // ----- Store the index
+ $v_header_list[$v_nb_extracted]['index'] = $i;
+
+ // ----- Look for the specific extract rules
+ $v_found = false;
+
+ // ----- Look for extract by name rule
+ if ( (isset($p_options[PCLZIP_OPT_BY_NAME]))
+ && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
+
+ // ----- Look if the filename is in the list
+ for ($j=0; ($j strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
+ && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
+ $v_found = true;
+ }
+ elseif ( (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */
+ && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
+ $v_found = true;
+ }
+ }
+ // ----- Look for a filename
+ elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
+ $v_found = true;
+ }
+ }
+ }
+
+ // ----- Look for extract by ereg rule
+ // ereg() is deprecated with PHP 5.3
+ /*
+ else if ( (isset($p_options[PCLZIP_OPT_BY_EREG]))
+ && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
+
+ if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
+ $v_found = true;
+ }
+ }
+ */
+
+ // ----- Look for extract by preg rule
+ else if ( (isset($p_options[PCLZIP_OPT_BY_PREG]))
+ && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
+
+ if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
+ $v_found = true;
+ }
+ }
+
+ // ----- Look for extract by index rule
+ else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX]))
+ && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
+
+ // ----- Look if the index is in the list
+ for ($j=$j_start; ($j=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
+ $v_found = true;
+ }
+ if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
+ $j_start = $j+1;
+ }
+
+ if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
+ break;
+ }
+ }
+ }
+ else {
+ $v_found = true;
+ }
+
+ // ----- Look for deletion
+ if ($v_found)
+ {
+ unset($v_header_list[$v_nb_extracted]);
+ }
+ else
+ {
+ $v_nb_extracted++;
+ }
+ }
+
+ // ----- Look if something need to be deleted
+ if ($v_nb_extracted > 0) {
+
+ // ----- Creates a temporay file
+ $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
+
+ // ----- Creates a temporary zip archive
+ $v_temp_zip = new PclZip($v_zip_temp_name);
+
+ // ----- Open the temporary zip file in write mode
+ if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) {
+ $this->privCloseFd();
+
+ // ----- Return
+ return $v_result;
+ }
+
+ // ----- Look which file need to be kept
+ for ($i=0; $izip_fd);
+ if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) {
+ // ----- Close the zip file
+ $this->privCloseFd();
+ $v_temp_zip->privCloseFd();
+ @unlink($v_zip_temp_name);
+
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Read the file header
+ $v_local_header = array();
+ if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) {
+ // ----- Close the zip file
+ $this->privCloseFd();
+ $v_temp_zip->privCloseFd();
+ @unlink($v_zip_temp_name);
+
+ // ----- Return
+ return $v_result;
+ }
+
+ // ----- Check that local file header is same as central file header
+ if ($this->privCheckFileHeaders($v_local_header,
+ $v_header_list[$i]) != 1) {
+ // TBC
+ }
+ unset($v_local_header);
+
+ // ----- Write the file header
+ if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) {
+ // ----- Close the zip file
+ $this->privCloseFd();
+ $v_temp_zip->privCloseFd();
+ @unlink($v_zip_temp_name);
+
+ // ----- Return
+ return $v_result;
+ }
+
+ // ----- Read/write the data block
+ if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) {
+ // ----- Close the zip file
+ $this->privCloseFd();
+ $v_temp_zip->privCloseFd();
+ @unlink($v_zip_temp_name);
+
+ // ----- Return
+ return $v_result;
+ }
+ }
+
+ // ----- Store the offset of the central dir
+ $v_offset = @ftell($v_temp_zip->zip_fd);
+
+ // ----- Re-Create the Central Dir files header
+ for ($i=0; $iprivWriteCentralFileHeader($v_header_list[$i])) != 1) {
+ $v_temp_zip->privCloseFd();
+ $this->privCloseFd();
+ @unlink($v_zip_temp_name);
+
+ // ----- Return
+ return $v_result;
+ }
+
+ // ----- Transform the header to a 'usable' info
+ $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
+ }
+
+
+ // ----- Zip file comment
+ $v_comment = '';
+ if (isset($p_options[PCLZIP_OPT_COMMENT])) {
+ $v_comment = $p_options[PCLZIP_OPT_COMMENT];
+ }
+
+ // ----- Calculate the size of the central header
+ $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset;
+
+ // ----- Create the central dir footer
+ if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) {
+ // ----- Reset the file list
+ unset($v_header_list);
+ $v_temp_zip->privCloseFd();
+ $this->privCloseFd();
+ @unlink($v_zip_temp_name);
+
+ // ----- Return
+ return $v_result;
+ }
+
+ // ----- Close
+ $v_temp_zip->privCloseFd();
+ $this->privCloseFd();
+
+ // ----- Delete the zip file
+ // TBC : I should test the result ...
+ @unlink($this->zipname);
+
+ // ----- Rename the temporary file
+ // TBC : I should test the result ...
+ //@rename($v_zip_temp_name, $this->zipname);
+ PclZipUtilRename($v_zip_temp_name, $this->zipname);
+
+ // ----- Destroy the temporary archive
+ unset($v_temp_zip);
+ }
+
+ // ----- Remove every files : reset the file
+ else if ($v_central_dir['entries'] != 0) {
+ $this->privCloseFd();
+
+ if (($v_result = $this->privOpenFd('wb')) != 1) {
+ return $v_result;
+ }
+
+ if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) {
+ return $v_result;
+ }
+
+ $this->privCloseFd();
+ }
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privDirCheck()
+ // Description :
+ // Check if a directory exists, if not it creates it and all the parents directory
+ // which may be useful.
+ // Parameters :
+ // $p_dir : Directory path to check.
+ // Return Values :
+ // 1 : OK
+ // -1 : Unable to create directory
+ // --------------------------------------------------------------------------------
+ function privDirCheck($p_dir, $p_is_dir=false)
+ {
+ $v_result = 1;
+
+
+ // ----- Remove the final '/'
+ if (($p_is_dir) && (substr($p_dir, -1)=='/'))
+ {
+ $p_dir = substr($p_dir, 0, strlen($p_dir)-1);
+ }
+
+ // ----- Check the directory availability
+ if ((is_dir($p_dir)) || ($p_dir == ""))
+ {
+ return 1;
+ }
+
+ // ----- Extract parent directory
+ $p_parent_dir = dirname($p_dir);
+
+ // ----- Just a check
+ if ($p_parent_dir != $p_dir)
+ {
+ // ----- Look for parent directory
+ if ($p_parent_dir != "")
+ {
+ if (($v_result = $this->privDirCheck($p_parent_dir)) != 1)
+ {
+ return $v_result;
+ }
+ }
+ }
+
+ // ----- Create the directory
+ if (!@mkdir($p_dir, 0777))
+ {
+ // ----- Error log
+ PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'");
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privMerge()
+ // Description :
+ // If $p_archive_to_add does not exist, the function exit with a success result.
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privMerge(&$p_archive_to_add)
+ {
+ $v_result=1;
+
+ // ----- Look if the archive_to_add exists
+ if (!is_file($p_archive_to_add->zipname))
+ {
+
+ // ----- Nothing to merge, so merge is a success
+ $v_result = 1;
+
+ // ----- Return
+ return $v_result;
+ }
+
+ // ----- Look if the archive exists
+ if (!is_file($this->zipname))
+ {
+
+ // ----- Do a duplicate
+ $v_result = $this->privDuplicate($p_archive_to_add->zipname);
+
+ // ----- Return
+ return $v_result;
+ }
+
+ // ----- Open the zip file
+ if (($v_result=$this->privOpenFd('rb')) != 1)
+ {
+ // ----- Return
+ return $v_result;
+ }
+
+ // ----- Read the central directory informations
+ $v_central_dir = array();
+ if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
+ {
+ $this->privCloseFd();
+ return $v_result;
+ }
+
+ // ----- Go to beginning of File
+ @rewind($this->zip_fd);
+
+ // ----- Open the archive_to_add file
+ if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1)
+ {
+ $this->privCloseFd();
+
+ // ----- Return
+ return $v_result;
+ }
+
+ // ----- Read the central directory informations
+ $v_central_dir_to_add = array();
+ if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1)
+ {
+ $this->privCloseFd();
+ $p_archive_to_add->privCloseFd();
+
+ return $v_result;
+ }
+
+ // ----- Go to beginning of File
+ @rewind($p_archive_to_add->zip_fd);
+
+ // ----- Creates a temporay file
+ $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
+
+ // ----- Open the temporary file in write mode
+ if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
+ {
+ $this->privCloseFd();
+ $p_archive_to_add->privCloseFd();
+
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Copy the files from the archive to the temporary file
+ // TBC : Here I should better append the file and go back to erase the central dir
+ $v_size = $v_central_dir['offset'];
+ while ($v_size != 0)
+ {
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+ $v_buffer = fread($this->zip_fd, $v_read_size);
+ @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
+ $v_size -= $v_read_size;
+ }
+
+ // ----- Copy the files from the archive_to_add into the temporary file
+ $v_size = $v_central_dir_to_add['offset'];
+ while ($v_size != 0)
+ {
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+ $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size);
+ @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
+ $v_size -= $v_read_size;
+ }
+
+ // ----- Store the offset of the central dir
+ $v_offset = @ftell($v_zip_temp_fd);
+
+ // ----- Copy the block of file headers from the old archive
+ $v_size = $v_central_dir['size'];
+ while ($v_size != 0)
+ {
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+ $v_buffer = @fread($this->zip_fd, $v_read_size);
+ @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
+ $v_size -= $v_read_size;
+ }
+
+ // ----- Copy the block of file headers from the archive_to_add
+ $v_size = $v_central_dir_to_add['size'];
+ while ($v_size != 0)
+ {
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+ $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size);
+ @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
+ $v_size -= $v_read_size;
+ }
+
+ // ----- Merge the file comments
+ $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment'];
+
+ // ----- Calculate the size of the (new) central header
+ $v_size = @ftell($v_zip_temp_fd)-$v_offset;
+
+ // ----- Swap the file descriptor
+ // Here is a trick : I swap the temporary fd with the zip fd, in order to use
+ // the following methods on the temporary fil and not the real archive fd
+ $v_swap = $this->zip_fd;
+ $this->zip_fd = $v_zip_temp_fd;
+ $v_zip_temp_fd = $v_swap;
+
+ // ----- Create the central dir footer
+ if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1)
+ {
+ $this->privCloseFd();
+ $p_archive_to_add->privCloseFd();
+ @fclose($v_zip_temp_fd);
+ $this->zip_fd = null;
+
+ // ----- Reset the file list
+ unset($v_header_list);
+
+ // ----- Return
+ return $v_result;
+ }
+
+ // ----- Swap back the file descriptor
+ $v_swap = $this->zip_fd;
+ $this->zip_fd = $v_zip_temp_fd;
+ $v_zip_temp_fd = $v_swap;
+
+ // ----- Close
+ $this->privCloseFd();
+ $p_archive_to_add->privCloseFd();
+
+ // ----- Close the temporary file
+ @fclose($v_zip_temp_fd);
+
+ // ----- Delete the zip file
+ // TBC : I should test the result ...
+ @unlink($this->zipname);
+
+ // ----- Rename the temporary file
+ // TBC : I should test the result ...
+ //@rename($v_zip_temp_name, $this->zipname);
+ PclZipUtilRename($v_zip_temp_name, $this->zipname);
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privDuplicate()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privDuplicate($p_archive_filename)
+ {
+ $v_result=1;
+
+ // ----- Look if the $p_archive_filename exists
+ if (!is_file($p_archive_filename))
+ {
+
+ // ----- Nothing to duplicate, so duplicate is a success.
+ $v_result = 1;
+
+ // ----- Return
+ return $v_result;
+ }
+
+ // ----- Open the zip file
+ if (($v_result=$this->privOpenFd('wb')) != 1)
+ {
+ // ----- Return
+ return $v_result;
+ }
+
+ // ----- Open the temporary file in write mode
+ if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0)
+ {
+ $this->privCloseFd();
+
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode');
+
+ // ----- Return
+ return PclZip::errorCode();
+ }
+
+ // ----- Copy the files from the archive to the temporary file
+ // TBC : Here I should better append the file and go back to erase the central dir
+ $v_size = filesize($p_archive_filename);
+ while ($v_size != 0)
+ {
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
+ $v_buffer = fread($v_zip_temp_fd, $v_read_size);
+ @fwrite($this->zip_fd, $v_buffer, $v_read_size);
+ $v_size -= $v_read_size;
+ }
+
+ // ----- Close
+ $this->privCloseFd();
+
+ // ----- Close the temporary file
+ @fclose($v_zip_temp_fd);
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privErrorLog()
+ // Description :
+ // Parameters :
+ // --------------------------------------------------------------------------------
+ function privErrorLog($p_error_code=0, $p_error_string='')
+ {
+ if (PCLZIP_ERROR_EXTERNAL == 1) {
+ PclError($p_error_code, $p_error_string);
+ }
+ else {
+ $this->error_code = $p_error_code;
+ $this->error_string = $p_error_string;
+ }
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privErrorReset()
+ // Description :
+ // Parameters :
+ // --------------------------------------------------------------------------------
+ function privErrorReset()
+ {
+ if (PCLZIP_ERROR_EXTERNAL == 1) {
+ PclErrorReset();
+ }
+ else {
+ $this->error_code = 0;
+ $this->error_string = '';
+ }
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privDisableMagicQuotes()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privDisableMagicQuotes()
+ {
+ $v_result=1;
+
+ // ----- Look if function exists
+ if ( (!function_exists("get_magic_quotes_runtime"))
+ || (!function_exists("set_magic_quotes_runtime"))) {
+ return $v_result;
+ }
+
+ // ----- Look if already done
+ if ($this->magic_quotes_status != -1) {
+ return $v_result;
+ }
+
+ // ----- Get and memorize the magic_quote value
+ $this->magic_quotes_status = @get_magic_quotes_runtime();
+
+ // ----- Disable magic_quotes
+ if ($this->magic_quotes_status == 1) {
+ @set_magic_quotes_runtime(0);
+ }
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : privSwapBackMagicQuotes()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function privSwapBackMagicQuotes()
+ {
+ $v_result=1;
+
+ // ----- Look if function exists
+ if ( (!function_exists("get_magic_quotes_runtime"))
+ || (!function_exists("set_magic_quotes_runtime"))) {
+ return $v_result;
+ }
+
+ // ----- Look if something to do
+ if ($this->magic_quotes_status != -1) {
+ return $v_result;
+ }
+
+ // ----- Swap back magic_quotes
+ if ($this->magic_quotes_status == 1) {
+ @set_magic_quotes_runtime($this->magic_quotes_status);
+ }
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ }
+ // End of class
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : PclZipUtilPathReduction()
+ // Description :
+ // Parameters :
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function PclZipUtilPathReduction($p_dir)
+ {
+ $v_result = "";
+
+ // ----- Look for not empty path
+ if ($p_dir != "") {
+ // ----- Explode path by directory names
+ $v_list = explode("/", $p_dir);
+
+ // ----- Study directories from last to first
+ $v_skip = 0;
+ for ($i=sizeof($v_list)-1; $i>=0; $i--) {
+ // ----- Look for current path
+ if ($v_list[$i] == ".") {
+ // ----- Ignore this directory
+ // Should be the first $i=0, but no check is done
+ }
+ else if ($v_list[$i] == "..") {
+ $v_skip++;
+ }
+ else if ($v_list[$i] == "") {
+ // ----- First '/' i.e. root slash
+ if ($i == 0) {
+ $v_result = "/".$v_result;
+ if ($v_skip > 0) {
+ // ----- It is an invalid path, so the path is not modified
+ // TBC
+ $v_result = $p_dir;
+ $v_skip = 0;
+ }
+ }
+ // ----- Last '/' i.e. indicates a directory
+ else if ($i == (sizeof($v_list)-1)) {
+ $v_result = $v_list[$i];
+ }
+ // ----- Double '/' inside the path
+ else {
+ // ----- Ignore only the double '//' in path,
+ // but not the first and last '/'
+ }
+ }
+ else {
+ // ----- Look for item to skip
+ if ($v_skip > 0) {
+ $v_skip--;
+ }
+ else {
+ $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:"");
+ }
+ }
+ }
+
+ // ----- Look for skip
+ if ($v_skip > 0) {
+ while ($v_skip > 0) {
+ $v_result = '../'.$v_result;
+ $v_skip--;
+ }
+ }
+ }
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : PclZipUtilPathInclusion()
+ // Description :
+ // This function indicates if the path $p_path is under the $p_dir tree. Or,
+ // said in an other way, if the file or sub-dir $p_path is inside the dir
+ // $p_dir.
+ // The function indicates also if the path is exactly the same as the dir.
+ // This function supports path with duplicated '/' like '//', but does not
+ // support '.' or '..' statements.
+ // Parameters :
+ // Return Values :
+ // 0 if $p_path is not inside directory $p_dir
+ // 1 if $p_path is inside directory $p_dir
+ // 2 if $p_path is exactly the same as $p_dir
+ // --------------------------------------------------------------------------------
+ function PclZipUtilPathInclusion($p_dir, $p_path)
+ {
+ $v_result = 1;
+
+ // ----- Look for path beginning by ./
+ if ( ($p_dir == '.')
+ || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) {
+ $p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1);
+ }
+ if ( ($p_path == '.')
+ || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) {
+ $p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1);
+ }
+
+ // ----- Explode dir and path by directory separator
+ $v_list_dir = explode("/", $p_dir);
+ $v_list_dir_size = sizeof($v_list_dir);
+ $v_list_path = explode("/", $p_path);
+ $v_list_path_size = sizeof($v_list_path);
+
+ // ----- Study directories paths
+ $i = 0;
+ $j = 0;
+ while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) {
+
+ // ----- Look for empty dir (path reduction)
+ if ($v_list_dir[$i] == '') {
+ $i++;
+ continue;
+ }
+ if ($v_list_path[$j] == '') {
+ $j++;
+ continue;
+ }
+
+ // ----- Compare the items
+ if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != '')) {
+ $v_result = 0;
+ }
+
+ // ----- Next items
+ $i++;
+ $j++;
+ }
+
+ // ----- Look if everything seems to be the same
+ if ($v_result) {
+ // ----- Skip all the empty items
+ while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++;
+ while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++;
+
+ if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) {
+ // ----- There are exactly the same
+ $v_result = 2;
+ }
+ else if ($i < $v_list_dir_size) {
+ // ----- The path is shorter than the dir
+ $v_result = 0;
+ }
+ }
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : PclZipUtilCopyBlock()
+ // Description :
+ // Parameters :
+ // $p_mode : read/write compression mode
+ // 0 : src & dest normal
+ // 1 : src gzip, dest normal
+ // 2 : src normal, dest gzip
+ // 3 : src & dest gzip
+ // Return Values :
+ // --------------------------------------------------------------------------------
+ function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0)
+ {
+ $v_result = 1;
+
+ if ($p_mode==0)
+ {
+ while ($p_size != 0)
+ {
+ $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
+ $v_buffer = @fread($p_src, $v_read_size);
+ @fwrite($p_dest, $v_buffer, $v_read_size);
+ $p_size -= $v_read_size;
+ }
+ }
+ else if ($p_mode==1)
+ {
+ while ($p_size != 0)
+ {
+ $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
+ $v_buffer = @gzread($p_src, $v_read_size);
+ @fwrite($p_dest, $v_buffer, $v_read_size);
+ $p_size -= $v_read_size;
+ }
+ }
+ else if ($p_mode==2)
+ {
+ while ($p_size != 0)
+ {
+ $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
+ $v_buffer = @fread($p_src, $v_read_size);
+ @gzwrite($p_dest, $v_buffer, $v_read_size);
+ $p_size -= $v_read_size;
+ }
+ }
+ else if ($p_mode==3)
+ {
+ while ($p_size != 0)
+ {
+ $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
+ $v_buffer = @gzread($p_src, $v_read_size);
+ @gzwrite($p_dest, $v_buffer, $v_read_size);
+ $p_size -= $v_read_size;
+ }
+ }
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : PclZipUtilRename()
+ // Description :
+ // This function tries to do a simple rename() function. If it fails, it
+ // tries to copy the $p_src file in a new $p_dest file and then unlink the
+ // first one.
+ // Parameters :
+ // $p_src : Old filename
+ // $p_dest : New filename
+ // Return Values :
+ // 1 on success, 0 on failure.
+ // --------------------------------------------------------------------------------
+ function PclZipUtilRename($p_src, $p_dest)
+ {
+ $v_result = 1;
+
+ // ----- Try to rename the files
+ if (!@rename($p_src, $p_dest)) {
+
+ // ----- Try to copy & unlink the src
+ if (!@copy($p_src, $p_dest)) {
+ $v_result = 0;
+ }
+ else if (!@unlink($p_src)) {
+ $v_result = 0;
+ }
+ }
+
+ // ----- Return
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : PclZipUtilOptionText()
+ // Description :
+ // Translate option value in text. Mainly for debug purpose.
+ // Parameters :
+ // $p_option : the option value.
+ // Return Values :
+ // The option text value.
+ // --------------------------------------------------------------------------------
+ function PclZipUtilOptionText($p_option)
+ {
+
+ $v_list = get_defined_constants();
+ for (reset($v_list); $v_key = key($v_list); next($v_list)) {
+ $v_prefix = substr($v_key, 0, 10);
+ if (( ($v_prefix == 'PCLZIP_OPT')
+ || ($v_prefix == 'PCLZIP_CB_')
+ || ($v_prefix == 'PCLZIP_ATT'))
+ && ($v_list[$v_key] == $p_option)) {
+ return $v_key;
+ }
+ }
+
+ $v_result = 'Unknown';
+
+ return $v_result;
+ }
+ // --------------------------------------------------------------------------------
+
+ // --------------------------------------------------------------------------------
+ // Function : PclZipUtilTranslateWinPath()
+ // Description :
+ // Translate windows path by replacing '\' by '/' and optionally removing
+ // drive letter.
+ // Parameters :
+ // $p_path : path to translate.
+ // $p_remove_disk_letter : true | false
+ // Return Values :
+ // The path translated.
+ // --------------------------------------------------------------------------------
+ function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true)
+ {
+ if (stristr(php_uname(), 'windows')) {
+ // ----- Look for potential disk letter
+ if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) {
+ $p_path = substr($p_path, $v_position+1);
+ }
+ // ----- Change potential windows directory separator
+ if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) {
+ $p_path = strtr($p_path, '\\', '/');
+ }
+ }
+ return $p_path;
+ }
+ // --------------------------------------------------------------------------------
+
+
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/include/photos_add_direct_prepare.inc.php b/Piwingo/piwigo-data/piwigo/admin/include/photos_add_direct_prepare.inc.php
new file mode 100644
index 0000000..7209c37
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/include/photos_add_direct_prepare.inc.php
@@ -0,0 +1,221 @@
+assign(
+ array(
+ 'F_ADD_ACTION'=> PHOTOS_ADD_BASE_URL,
+ 'chunk_size' => $conf['upload_form_chunk_size'],
+ 'max_file_size' => $conf['upload_form_max_file_size'],
+ 'ADMIN_PAGE_TITLE' => l10n('Upload Photos'),
+ )
+ );
+
+// what is the maximum number of pixels permitted by the memory_limit?
+if (pwg_image::get_library() == 'gd')
+{
+ $fudge_factor = 1.7;
+ $available_memory = get_ini_size('memory_limit') - memory_get_usage();
+ $max_upload_width = round(sqrt($available_memory/(2 * $fudge_factor)));
+ $max_upload_height = round(2 * $max_upload_width / 3);
+
+ // we don't want dimensions like 2995x1992 but 3000x2000
+ $max_upload_width = round($max_upload_width/100)*100;
+ $max_upload_height = round($max_upload_height/100)*100;
+
+ $max_upload_resolution = floor($max_upload_width * $max_upload_height / (1000000));
+
+ // no need to display a limitation warning if the limitation is huge like 20MP
+ if ($max_upload_resolution < 25)
+ {
+ $template->assign(
+ array(
+ 'max_upload_width' => $max_upload_width,
+ 'max_upload_height' => $max_upload_height,
+ 'max_upload_resolution' => $max_upload_resolution,
+ )
+ );
+ }
+}
+
+//warn the user if the picture will be resized after upload
+if ($conf['original_resize'])
+{
+ $template->assign(
+ array(
+ 'original_resize_maxwidth' => $conf['original_resize_maxwidth'],
+ 'original_resize_maxheight' => $conf['original_resize_maxheight'],
+ )
+ );
+}
+
+
+$template->assign(
+ array(
+ 'form_action' => PHOTOS_ADD_BASE_URL,
+ 'pwg_token' => get_pwg_token(),
+ )
+ );
+
+$unique_exts = array_unique(
+ array_map(
+ 'strtolower',
+ $conf['upload_form_all_types'] ? $conf['file_ext'] : $conf['picture_ext']
+ )
+ );
+
+$template->assign(
+ array(
+ 'upload_file_types' => implode(', ', $unique_exts),
+ 'file_exts' => implode(',', $unique_exts),
+ )
+ );
+
+// +-----------------------------------------------------------------------+
+// | Categories |
+// +-----------------------------------------------------------------------+
+
+// we need to know the category in which the last photo was added
+$selected_category = array();
+
+if (isset($_GET['album']))
+{
+ // set the category from get url or ...
+ check_input_parameter('album', $_GET, false, PATTERN_ID);
+
+ // test if album really exists
+ $query = '
+SELECT id, uppercats
+ FROM '.CATEGORIES_TABLE.'
+ WHERE id = '.$_GET['album'].'
+;';
+ $result = pwg_query($query);
+ if (pwg_db_num_rows($result) == 1)
+ {
+ $selected_category = array($_GET['album']);
+
+ $cat = pwg_db_fetch_assoc($result);
+ $template->assign('ADD_TO_ALBUM', get_cat_display_name_cache($cat['uppercats'], null));
+ }
+ else
+ {
+ fatal_error('[Hacking attempt] the album id = "'.$_GET['album'].'" is not valid');
+ }
+}
+else
+{
+ // we need to know the category in which the last photo was added
+ $query = '
+SELECT category_id, c.uppercats
+ FROM '.IMAGES_TABLE.' AS i
+ JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON image_id = i.id
+ JOIN '.CATEGORIES_TABLE.' AS c ON category_id = c.id
+ ORDER BY i.id DESC
+ LIMIT 1
+;
+';
+ $result = pwg_query($query);
+ if (pwg_db_num_rows($result) > 0)
+ {
+ $row = pwg_db_fetch_assoc($result);
+ $selected_category = array($row['category_id']);
+ $selected_category_name = get_cat_display_name_cache($row['uppercats'], null);
+ $template->assign('selected_category_name', $selected_category_name);
+ }
+}
+
+// existing album
+$template->assign('selected_category', $selected_category);
+
+// how many existing albums?
+$query = '
+SELECT
+ COUNT(*)
+ FROM '.CATEGORIES_TABLE.'
+;';
+list($nb_albums) = pwg_db_fetch_row(pwg_query($query));
+// $nb_albums = 0;
+$template->assign('NB_ALBUMS', $nb_albums);
+
+// image level options
+$selected_level = isset($_POST['level']) ? $_POST['level'] : 0;
+$template->assign(
+ array(
+ 'level_options'=> get_privacy_level_options(),
+ 'level_options_selected' => array($selected_level)
+ )
+ );
+
+// +-----------------------------------------------------------------------+
+// | Setup errors/warnings |
+// +-----------------------------------------------------------------------+
+
+// Errors
+$setup_errors = array();
+
+$error_message = ready_for_upload_message();
+if (!empty($error_message))
+{
+ $setup_errors[] = $error_message;
+}
+
+if (!function_exists('gd_info'))
+{
+ $setup_errors[] = l10n('GD library is missing');
+}
+
+$template->assign(array(
+ 'setup_errors'=> $setup_errors,
+ 'CACHE_KEYS' => get_admin_client_cache_keys(array('categories')),
+ ));
+
+// Warnings
+if (isset($_GET['hide_warnings']))
+{
+ $_SESSION['upload_hide_warnings'] = true;
+}
+
+if (!isset($_SESSION['upload_hide_warnings']))
+{
+ $setup_warnings = array();
+
+ if ($conf['use_exif'] and !function_exists('exif_read_data'))
+ {
+ $setup_warnings[] = l10n('Exif extension not available, admin should disable exif use');
+ }
+
+ if (get_ini_size('upload_max_filesize') > get_ini_size('post_max_size'))
+ {
+ $setup_warnings[] = l10n(
+ 'In your php.ini file, the upload_max_filesize (%sB) is bigger than post_max_size (%sB), you should change this setting',
+ get_ini_size('upload_max_filesize', false),
+ get_ini_size('post_max_size', false)
+ );
+ }
+
+ if (get_ini_size('upload_max_filesize') < $conf['upload_form_chunk_size']*1024)
+ {
+ $setup_warnings[] = sprintf(
+ 'Piwigo setting upload_form_chunk_size (%ukB) should be smaller than PHP configuration setting upload_max_filesize (%ukB)',
+ $conf['upload_form_chunk_size'],
+ ceil(get_ini_size('upload_max_filesize') / 1024)
+ );
+ }
+
+ $template->assign(
+ array(
+ 'setup_warnings' => $setup_warnings,
+ 'hide_warnings_link' => PHOTOS_ADD_BASE_URL.'&hide_warnings=1'
+ )
+ );
+}
+
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/include/plugins.class.php b/Piwingo/piwigo-data/piwigo/admin/include/plugins.class.php
new file mode 100644
index 0000000..dd2cf95
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/include/plugins.class.php
@@ -0,0 +1,843 @@
+plugin_id, $plugin_version, $errors);
+ }
+ }
+ function activate($plugin_version, &$errors=array())
+ {
+ if (is_callable('plugin_activate'))
+ {
+ return plugin_activate($this->plugin_id, $plugin_version, $errors);
+ }
+ }
+ function deactivate()
+ {
+ if (is_callable('plugin_deactivate'))
+ {
+ return plugin_deactivate($this->plugin_id);
+ }
+ }
+ function uninstall()
+ {
+ if (is_callable('plugin_uninstall'))
+ {
+ return plugin_uninstall($this->plugin_id);
+ }
+ }
+ function update($old_version, $new_version, &$errors=array()) {}
+}
+
+
+class plugins
+{
+ var $fs_plugins = array();
+ var $db_plugins_by_id = array();
+ var $server_plugins = array();
+ var $default_plugins = array('LocalFilesEditor', 'language_switch', 'TakeATour', 'AdminTools');
+
+ /**
+ * Initialize $fs_plugins and $db_plugins_by_id
+ */
+ function __construct()
+ {
+ $this->get_fs_plugins();
+
+ foreach (get_db_plugins() as $db_plugin)
+ {
+ $this->db_plugins_by_id[$db_plugin['id']] = $db_plugin;
+ }
+ }
+
+ /**
+ * Returns the maintain class of a plugin
+ * or build a new class with the procedural methods
+ * @param string $plugin_id
+ */
+ private static function build_maintain_class($plugin_id)
+ {
+ $file_to_include = PHPWG_PLUGINS_PATH . $plugin_id . '/maintain';
+ $classname = $plugin_id.'_maintain';
+
+ // piwigo-videojs and piwigo-openstreetmap unfortunately have a "-" in their folder
+ // name (=plugin_id) and a class name can't have a "-". So we have to replace with a "_"
+ $classname = str_replace('-', '_', $classname);
+
+ // 2.7 pattern (OO only)
+ if (file_exists($file_to_include.'.class.php'))
+ {
+ include_once($file_to_include.'.class.php');
+ return new $classname($plugin_id);
+ }
+
+ // before 2.7 pattern (OO or procedural)
+ if (file_exists($file_to_include.'.inc.php'))
+ {
+ include_once($file_to_include.'.inc.php');
+
+ if (class_exists($classname))
+ {
+ return new $classname($plugin_id);
+ }
+ }
+
+ return new DummyPlugin_maintain($plugin_id);
+ }
+
+ /**
+ * Perform requested actions
+ * @param string - action
+ * @param string - plugin id
+ * @param array - errors
+ */
+ function perform_action($action, $plugin_id, $options=array())
+ {
+ global $conf;
+
+ if (!$conf['enable_extensions_install'] and 'delete' == $action)
+ {
+ die('Piwigo extensions install/update/delete system is disabled');
+ }
+
+ if (isset($this->db_plugins_by_id[$plugin_id]))
+ {
+ $crt_db_plugin = $this->db_plugins_by_id[$plugin_id];
+ }
+
+ if ($action !== 'update')
+ { // wait for files to be updated
+ $plugin_maintain = self::build_maintain_class($plugin_id);
+ }
+
+ $activity_details = array('plugin_id'=>$plugin_id);
+
+ $errors = array();
+
+ switch ($action)
+ {
+ case 'install':
+ if (!empty($crt_db_plugin) or !isset($this->fs_plugins[$plugin_id]))
+ {
+ break;
+ }
+
+ $plugin_maintain->install($this->fs_plugins[$plugin_id]['version'], $errors);
+ $activity_details['version'] = $this->fs_plugins[$plugin_id]['version'];
+
+ if (empty($errors))
+ {
+ $query = '
+INSERT INTO '. PLUGINS_TABLE .' (id,version)
+ VALUES (\''. $plugin_id .'\', \''. $this->fs_plugins[$plugin_id]['version'] .'\')
+;';
+ pwg_query($query);
+ }
+ else
+ {
+ $activity_details['result'] = 'error';
+ }
+ break;
+
+ case 'update':
+ $previous_version = $this->fs_plugins[$plugin_id]['version'];
+ $activity_details['from_version'] = $previous_version;
+ $errors[0] = $this->extract_plugin_files('upgrade', $options['revision'], $plugin_id);
+
+ if ($errors[0] === 'ok')
+ {
+ $this->get_fs_plugin($plugin_id); // refresh plugins list
+ $new_version = $this->fs_plugins[$plugin_id]['version'];
+ $activity_details['to_version'] = $new_version;
+
+ $plugin_maintain = self::build_maintain_class($plugin_id);
+ $plugin_maintain->update($previous_version, $new_version, $errors);
+
+ if ($new_version != 'auto')
+ {
+ $query = '
+UPDATE '. PLUGINS_TABLE .'
+ SET version=\''. $new_version .'\'
+ WHERE id=\''. $plugin_id .'\'
+;';
+ pwg_query($query);
+ }
+ }
+ else
+ {
+ $activity_details['result'] = 'error';
+ }
+
+
+ break;
+
+ case 'activate':
+ if (!isset($crt_db_plugin))
+ {
+ $errors = $this->perform_action('install', $plugin_id);
+ list($crt_db_plugin) = get_db_plugins(null, $plugin_id);
+ load_conf_from_db();
+ }
+ elseif ($crt_db_plugin['state'] == 'active')
+ {
+ break;
+ }
+
+ if (empty($errors))
+ {
+ $plugin_maintain->activate($crt_db_plugin['version'], $errors);
+ $activity_details['version'] = $crt_db_plugin['version'];
+ }
+
+ if (empty($errors))
+ {
+ $query = '
+UPDATE '. PLUGINS_TABLE .'
+ SET state=\'active\'
+ WHERE id=\''. $plugin_id .'\'
+;';
+ pwg_query($query);
+ }
+ else
+ {
+ $activity_details['result'] = 'error';
+ }
+ break;
+
+ case 'deactivate':
+ if (!isset($crt_db_plugin) or $crt_db_plugin['state'] != 'active')
+ {
+ $activity_details['result'] = 'error';
+ break;
+ }
+
+ $query = '
+UPDATE '. PLUGINS_TABLE .'
+ SET state=\'inactive\'
+ WHERE id=\''. $plugin_id .'\'
+;';
+ pwg_query($query);
+
+ $plugin_maintain->deactivate();
+
+ if (isset($crt_db_plugin['version']))
+ {
+ $activity_details['version'] = $crt_db_plugin['version'];
+ }
+
+ break;
+
+ case 'uninstall':
+ if (!isset($crt_db_plugin))
+ {
+ $activity_details['result'] = 'error';
+ $activity_details['error'] = 'plugin not installed';
+ break;
+ }
+
+ if (isset($crt_db_plugin['version']))
+ {
+ $activity_details['version'] = $crt_db_plugin['version'];
+ }
+
+ if ($crt_db_plugin['state'] == 'active')
+ {
+ $this->perform_action('deactivate', $plugin_id);
+ }
+
+ $query = '
+DELETE FROM '. PLUGINS_TABLE .'
+ WHERE id=\''. $plugin_id .'\'
+;';
+ pwg_query($query);
+
+ $plugin_maintain->uninstall();
+ break;
+
+ case 'restore':
+ $this->perform_action('uninstall', $plugin_id);
+ unset($this->db_plugins_by_id[$plugin_id]);
+ $errors = $this->perform_action('activate', $plugin_id);
+ break;
+
+ case 'delete':
+ if (!empty($crt_db_plugin))
+ {
+ if (isset($crt_db_plugin['version']))
+ {
+ $activity_details['db_version'] = $crt_db_plugin['version'];
+ }
+
+ $this->perform_action('uninstall', $plugin_id);
+ }
+ if (!isset($this->fs_plugins[$plugin_id]))
+ {
+ break;
+ }
+ else
+ {
+ $activity_details['fs_version'] = $this->fs_plugins[$plugin_id]['version'];
+ }
+
+ include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+ deltree(PHPWG_PLUGINS_PATH . $plugin_id, PHPWG_PLUGINS_PATH . 'trash');
+ break;
+ }
+
+ pwg_activity('system', ACTIVITY_SYSTEM_PLUGIN, $action, $activity_details);
+
+ return $errors;
+ }
+
+ /**
+ * Get plugins defined in the plugin directory
+ */
+ function get_fs_plugins()
+ {
+ $dir = opendir(PHPWG_PLUGINS_PATH);
+ while ($file = readdir($dir))
+ {
+ if ($file!='.' and $file!='..')
+ {
+ if (preg_match('/^[a-zA-Z0-9-_]+$/', $file))
+ {
+ $this->get_fs_plugin($file);
+ }
+ }
+ }
+ closedir($dir);
+ }
+
+ /**
+ * Load metadata of a plugin in `fs_plugins` array
+ * @from 2.7
+ * @param $plugin_id
+ * @return false|array
+ */
+ function get_fs_plugin($plugin_id)
+ {
+ $path = PHPWG_PLUGINS_PATH.$plugin_id;
+
+ if (is_dir($path) and !is_link($path)
+ and file_exists($path.'/main.inc.php')
+ )
+ {
+ $plugin = array(
+ 'name'=>$plugin_id,
+ 'version'=>'0',
+ 'uri'=>'',
+ 'description'=>'',
+ 'author'=>'',
+ 'hasSettings'=>false,
+ );
+ $plg_data = file_get_contents($path.'/main.inc.php', false, null, 0, 2048);
+
+ if (preg_match("|Plugin Name:\\s*(.+)|", $plg_data, $val))
+ {
+ $plugin['name'] = trim( $val[1] );
+ }
+ if (preg_match("|Version:\\s*([\\w.-]+)|", $plg_data, $val))
+ {
+ $plugin['version'] = trim($val[1]);
+ }
+ if (preg_match("|Plugin URI:\\s*(https?:\\/\\/.+)|", $plg_data, $val))
+ {
+ $plugin['uri'] = trim($val[1]);
+ }
+ if ($desc = load_language('description.txt', $path.'/', array('return' => true)))
+ {
+ $plugin['description'] = trim($desc);
+ }
+ elseif (preg_match("|Description:\\s*(.+)|", $plg_data, $val))
+ {
+ $plugin['description'] = trim($val[1]);
+ }
+ if (preg_match("|Author:\\s*(.+)|", $plg_data, $val))
+ {
+ $plugin['author'] = trim($val[1]);
+ }
+ if (preg_match("|Author URI:\\s*(https?:\\/\\/.+)|", $plg_data, $val))
+ {
+ $plugin['author uri'] = trim($val[1]);
+ }
+ if (preg_match("/Has Settings:\\s*([Tt]rue|[Ww]ebmaster)/", $plg_data, $val))
+ {
+ if (strtolower($val[1]) == 'webmaster')
+ {
+ global $user;
+
+ if (isset($user) and 'webmaster' == $user['status'])
+ {
+ $plugin['hasSettings'] = true;
+ }
+ }
+ else
+ {
+ $plugin['hasSettings'] = true;
+ }
+ }
+ if (!empty($plugin['uri']) and strpos($plugin['uri'] , 'extension_view.php?eid='))
+ {
+ list( , $extension) = explode('extension_view.php?eid=', $plugin['uri']);
+ if (is_numeric($extension)) $plugin['extension'] = $extension;
+ }
+
+ // IMPORTANT SECURITY !
+ $plugin = array_map('htmlspecialchars', $plugin);
+ $this->fs_plugins[$plugin_id] = $plugin;
+
+ return $plugin;
+ }
+
+ return false;
+ }
+
+ /**
+ * Sort fs_plugins
+ */
+ function sort_fs_plugins($order='name')
+ {
+ switch ($order)
+ {
+ case 'name':
+ uasort($this->fs_plugins, 'name_compare');
+ break;
+ case 'status':
+ $this->sort_plugins_by_state();
+ break;
+ case 'author':
+ uasort($this->fs_plugins, array($this, 'plugin_author_compare'));
+ break;
+ case 'id':
+ uksort($this->fs_plugins, 'strcasecmp');
+ break;
+ }
+ }
+
+ // Retrieve PEM versions
+ // Beta test : return last version on PEM if the current version isn't known or else return the current and the last version
+ function get_versions_to_check($beta_test=false, $version=PHPWG_VERSION)
+ {
+ global $conf;
+
+ $versions_to_check = array();
+ $url = PEM_URL . '/api/get_version_list.php?category_id='. $conf['pem_plugins_category'] .'&format=php';
+ if (fetchRemote($url, $result) and $pem_versions = @unserialize($result))
+ {
+ $i = 0;
+
+ // If the actual version exist, put the PEM id in $versions_to_check
+ while ($i < count($pem_versions) && count($versions_to_check) == 0)
+ {
+ if (get_branch_from_version($pem_versions[$i]['name']) == get_branch_from_version($version))
+ {
+ $versions_to_check[] = $pem_versions[$i]['id'];
+ }
+ $i++;
+ }
+
+ // If $beta_test is true, search the previous version
+ if ($beta_test)
+ {
+ // If the actual version is not in PEM, put the latest PEM version
+ if (count($versions_to_check) == 0)
+ {
+ $versions_to_check[] = $pem_versions[0]['id'];
+ }
+ else // Else search the next version in PEM
+ {
+ $has_found_previous_version = false;
+ while ($i < count($pem_versions) && !$has_found_previous_version)
+ {
+ if ($pem_versions[$i]['id'] != $versions_to_check[0])
+ {
+ $versions_to_check[] = $pem_versions[$i]['id'];
+ $has_found_previous_version = true;
+ }
+ $i++;
+ }
+ }
+ }
+
+ // if (!preg_match('/^\d+\.\d+\.\d+$/', $version))
+ // {
+ // $version = $pem_versions[0]['name'];
+ // }
+ // $branch = get_branch_from_version($version);
+ // foreach ($pem_versions as $pem_version)
+ // {
+ // if (strpos($pem_version['name'], $branch) === 0)
+ // {
+ // $versions_to_check[] = $pem_version['id'];
+ // }
+ // }
+ }
+ return $versions_to_check;
+ }
+
+ /**
+ * Retrieve PEM server datas to $server_plugins
+ * $beta_test parameter add plugins compatible with the previous version
+ */
+ function get_server_plugins($new=false, $beta_test=false)
+ {
+ global $user, $conf;
+
+ $versions_to_check = $this->get_versions_to_check($beta_test);
+ if (empty($versions_to_check))
+ {
+ return true;
+ }
+
+ // Plugins to check
+ $plugins_to_check = array();
+ foreach($this->fs_plugins as $fs_plugin)
+ {
+ if (isset($fs_plugin['extension']))
+ {
+ $plugins_to_check[] = $fs_plugin['extension'];
+ }
+ }
+
+ // Retrieve PEM plugins infos
+ $url = PEM_URL . '/api/get_revision_list-next.php';
+ $get_data = array(
+ 'category_id' => $conf['pem_plugins_category'],
+ 'format' => 'php',
+ 'last_revision_only' => 'true',
+ 'version' => implode(',', $versions_to_check),
+ 'lang' => substr($user['language'], 0, 2),
+ 'get_nb_downloads' => 'true',
+ );
+
+ if (!empty($plugins_to_check))
+ {
+ if ($new)
+ {
+ $get_data['extension_exclude'] = implode(',', $plugins_to_check);
+ }
+ else
+ {
+ $get_data['extension_include'] = implode(',', $plugins_to_check);
+ }
+ }
+ if (fetchRemote($url, $result, $get_data))
+ {
+ $pem_plugins = @unserialize($result);
+ if (!is_array($pem_plugins))
+ {
+ return false;
+ }
+ foreach ($pem_plugins as $plugin)
+ {
+ $this->server_plugins[$plugin['extension_id']] = $plugin;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ function get_incompatible_plugins($actualize=false)
+ {
+ if (isset($_SESSION['incompatible_plugins']) and !$actualize
+ and $_SESSION['incompatible_plugins']['~~expire~~'] > time())
+ {
+ return $_SESSION['incompatible_plugins'];
+ }
+
+ $_SESSION['incompatible_plugins'] = array('~~expire~~' => time() + 300);
+
+ $versions_to_check = $this->get_versions_to_check();
+ if (empty($versions_to_check))
+ {
+ return false;
+ }
+
+ global $conf;
+
+ // Plugins to check
+ $plugins_to_check = array();
+ foreach($this->fs_plugins as $fs_plugin)
+ {
+ if (isset($fs_plugin['extension']))
+ {
+ $plugins_to_check[] = $fs_plugin['extension'];
+ }
+ }
+
+ // Retrieve PEM plugins infos
+ $url = PEM_URL . '/api/get_revision_list.php';
+ $get_data = array(
+ 'category_id' => $conf['pem_plugins_category'],
+ 'format' => 'php',
+ 'version' => implode(',', $versions_to_check),
+ 'extension_include' => implode(',', $plugins_to_check),
+ );
+
+ if (fetchRemote($url, $result, $get_data))
+ {
+ $pem_plugins = @unserialize($result);
+ if (!is_array($pem_plugins))
+ {
+ return false;
+ }
+
+ $server_plugins = array();
+ foreach ($pem_plugins as $plugin)
+ {
+ if (!isset($server_plugins[$plugin['extension_id']]))
+ {
+ $server_plugins[$plugin['extension_id']] = array();
+ }
+ $server_plugins[$plugin['extension_id']][] = $plugin['revision_name'];
+ }
+
+ foreach ($this->fs_plugins as $plugin_id => $fs_plugin)
+ {
+ if (isset($fs_plugin['extension'])
+ and !in_array($plugin_id, $this->default_plugins)
+ and $fs_plugin['version'] != 'auto'
+ and (!isset($server_plugins[$fs_plugin['extension']]) or !in_array($fs_plugin['version'], $server_plugins[$fs_plugin['extension']])))
+ {
+ $_SESSION['incompatible_plugins'][$plugin_id] = $fs_plugin['version'];
+ }
+ }
+ return $_SESSION['incompatible_plugins'];
+ }
+ return false;
+ }
+
+ /**
+ * Sort $server_plugins
+ */
+ function sort_server_plugins($order='date')
+ {
+ switch ($order)
+ {
+ case 'date':
+ krsort($this->server_plugins);
+ break;
+ case 'revision':
+ usort($this->server_plugins, array($this, 'extension_revision_compare'));
+ break;
+ case 'name':
+ uasort($this->server_plugins, array($this, 'extension_name_compare'));
+ break;
+ case 'author':
+ uasort($this->server_plugins, array($this, 'extension_author_compare'));
+ break;
+ case 'downloads':
+ usort($this->server_plugins, array($this, 'extension_downloads_compare'));
+ break;
+ }
+ }
+
+ /**
+ * Extract plugin files from archive
+ * @param string - install or upgrade
+ * @param string - archive URL
+ * @param string - plugin id or extension id
+ */
+ function extract_plugin_files($action, $revision, $dest, &$plugin_id=null)
+ {
+ global $logger;
+
+ if ($archive = tempnam( PHPWG_PLUGINS_PATH, 'zip'))
+ {
+ $url = PEM_URL . '/download.php';
+ $get_data = array(
+ 'rid' => $revision,
+ 'origin' => 'piwigo_'.$action,
+ );
+
+ if ($handle = @fopen($archive, 'wb') and fetchRemote($url, $handle, $get_data))
+ {
+ fclose($handle);
+ include_once(PHPWG_ROOT_PATH.'admin/include/pclzip.lib.php');
+ $zip = new PclZip($archive);
+ if ($list = $zip->listContent())
+ {
+ foreach ($list as $file)
+ {
+ // we search main.inc.php in archive
+ if (basename($file['filename']) == 'main.inc.php'
+ and (!isset($main_filepath)
+ or strlen($file['filename']) < strlen($main_filepath)))
+ {
+ $main_filepath = $file['filename'];
+ }
+ }
+
+ $logger->debug(__FUNCTION__.', $main_filepath = '.$main_filepath);
+
+ if (isset($main_filepath))
+ {
+ $root = dirname($main_filepath); // main.inc.php path in archive
+ if ($action == 'upgrade')
+ {
+ $plugin_id = $dest;
+ }
+ else
+ {
+ $plugin_id = ($root == '.' ? 'extension_' . $dest : basename($root));
+ }
+ $extract_path = PHPWG_PLUGINS_PATH . $plugin_id;
+ $logger->debug(__FUNCTION__.', $extract_path = '.$extract_path);
+
+ if($result = $zip->extract(PCLZIP_OPT_PATH, $extract_path,
+ PCLZIP_OPT_REMOVE_PATH, $root,
+ PCLZIP_OPT_REPLACE_NEWER))
+ {
+ foreach ($result as $file)
+ {
+ if ($file['stored_filename'] == $main_filepath)
+ {
+ $status = $file['status'];
+ break;
+ }
+ }
+ if (file_exists($extract_path.'/obsolete.list')
+ and $old_files = file($extract_path.'/obsolete.list', FILE_IGNORE_NEW_LINES)
+ and !empty($old_files))
+ {
+ $old_files[] = 'obsolete.list';
+ $logger->debug(__FUNCTION__.', $old_files = {'.join('},{', $old_files).'}');
+
+ $extract_path_realpath = realpath($extract_path);
+
+ foreach($old_files as $old_file)
+ {
+ $old_file = trim($old_file);
+ $old_file = trim($old_file, '/'); // prevent path starting with a "/"
+
+ if (empty($old_file)) // empty here means the extension itself
+ {
+ continue;
+ }
+
+ $path = $extract_path.'/'.$old_file;
+
+ // make sure the obsolete file is withing the extension directory, prevent traversal path
+ $realpath = realpath($path);
+ if ($realpath === false or strpos($realpath, $extract_path_realpath) !== 0)
+ {
+ continue;
+ }
+
+ $logger->debug(__FUNCTION__.', to delete = '.$path);
+
+ if (is_file($path))
+ {
+ @unlink($path);
+ }
+ elseif (is_dir($path))
+ {
+ deltree($path, PHPWG_PLUGINS_PATH . 'trash');
+ }
+ }
+ }
+ }
+ else $status = 'extract_error';
+ }
+ else $status = 'archive_error';
+ }
+ else $status = 'archive_error';
+ }
+ else $status = 'dl_archive_error';
+ }
+ else $status = 'temp_path_error';
+
+ @unlink($archive);
+ return $status;
+ }
+
+ function get_merged_extensions($version=PHPWG_VERSION)
+ {
+ $file = PHPWG_ROOT_PATH.'install/obsolete_extensions.list';
+ $merged_extensions = array();
+
+ if (file_exists($file) and $obsolete_ext = file($file, FILE_IGNORE_NEW_LINES) and !empty($obsolete_ext))
+ {
+ foreach ($obsolete_ext as $ext)
+ {
+ if (preg_match('/^(\d+) ?: ?(.*?)$/', $ext, $matches))
+ {
+ $merged_extensions[$matches[1]] = $matches[2];
+ }
+ }
+ }
+ return $merged_extensions;
+ }
+
+ /**
+ * Sort functions
+ */
+ function extension_revision_compare($a, $b)
+ {
+ if ($a['revision_date'] < $b['revision_date']) return 1;
+ else return -1;
+ }
+
+ function extension_name_compare($a, $b)
+ {
+ return strcmp(strtolower($a['extension_name']), strtolower($b['extension_name']));
+ }
+
+ function extension_author_compare($a, $b)
+ {
+ $r = strcasecmp($a['author_name'], $b['author_name']);
+ if ($r == 0) return $this->extension_name_compare($a, $b);
+ else return $r;
+ }
+
+ function plugin_author_compare($a, $b)
+ {
+ $r = strcasecmp($a['author'], $b['author']);
+ if ($r == 0) return name_compare($a, $b);
+ else return $r;
+ }
+
+ function extension_downloads_compare($a, $b)
+ {
+ if ($a['extension_nb_downloads'] < $b['extension_nb_downloads']) return 1;
+ else return -1;
+ }
+
+ function sort_plugins_by_state()
+ {
+ uasort($this->fs_plugins, 'name_compare');
+
+ $active_plugins = array();
+ $inactive_plugins = array();
+ $not_installed = array();
+
+ foreach($this->fs_plugins as $plugin_id => $plugin)
+ {
+ if (isset($this->db_plugins_by_id[$plugin_id]))
+ {
+ $this->db_plugins_by_id[$plugin_id]['state'] == 'active' ?
+ $active_plugins[$plugin_id] = $plugin : $inactive_plugins[$plugin_id] = $plugin;
+ }
+ else
+ {
+ $not_installed[$plugin_id] = $plugin;
+ }
+ }
+ $this->fs_plugins = $active_plugins + $inactive_plugins + $not_installed;
+ }
+}
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/include/tabsheet.class.php b/Piwingo/piwigo-data/piwigo/admin/include/tabsheet.class.php
new file mode 100644
index 0000000..52f25f1
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/include/tabsheet.class.php
@@ -0,0 +1,144 @@
+sheets = array();
+ $this->uniqid = null;
+ $this->name = $name;
+ $this->titlename = $titlename;
+ $this->selected = "";
+ }
+
+ function set_id($id)
+ {
+ $this->uniqid = $id;
+ }
+
+ /*
+ add a tab
+ */
+ function add($name, $caption, $url, $selected = false)
+ {
+ if (!isset($this->sheets[$name]))
+ {
+ $this->sheets[$name] = array('caption' => $caption,
+ 'url' => $url);
+ if($selected)
+ {
+ $this->selected=$name;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /*
+ remove a tab
+ */
+ function delete($name)
+ {
+ if (isset($this->sheets[$name]))
+ {
+ array_splice($this->sheets, $name, 1);
+
+ if ($this->selected == $name)
+ {
+ $this->selected = "";
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /*
+ select a tab to be active
+ */
+ function select($name)
+ {
+ $this->sheets = trigger_change('tabsheet_before_select', $this->sheets, $this->uniqid);
+ if (!array_key_exists($name, $this->sheets))
+ {
+ $keys = array_keys($this->sheets);
+ $name = $keys[0];
+ }
+ $this->selected = $name;
+ }
+
+ /*
+ set $titlename value
+ */
+ function set_titlename($titlename)
+ {
+ $this->titlename = $titlename;
+ return $this->titlename;
+ }
+
+ /*
+ returns $titlename value
+ */
+ function get_titlename()
+ {
+ return $this->titlename;
+ }
+
+ /*
+ returns properties of selected tab
+ */
+ function get_selected()
+ {
+ if (!empty($this->selected))
+ {
+ return $this->sheets[$this->selected];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /*
+ * Build TabSheet and assign this content to current page
+ *
+ * Fill $this->$name {default value = TABSHEET} with HTML code for tabsheet
+ * Fill $this->titlename {default value = TABSHEET_TITLE} with formated caption of the selected tab
+ */
+ function assign()
+ {
+ global $template;
+
+ $template->set_filename('tabsheet', 'tabsheet.tpl');
+ $template->assign('tabsheet', $this->sheets);
+ $template->assign('tabsheet_selected', $this->selected);
+
+ $selected_tab = $this->get_selected();
+
+ if (isset($selected_tab))
+ {
+ $template->assign(
+ array($this->titlename => '['.$selected_tab['caption'].']'));
+ }
+
+ $template->assign_var_from_handle($this->name, 'tabsheet');
+ $template->clear_assign('tabsheet');
+ }
+}
+
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/include/themes.class.php b/Piwingo/piwigo-data/piwigo/admin/include/themes.class.php
new file mode 100644
index 0000000..1bc7735
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/include/themes.class.php
@@ -0,0 +1,770 @@
+theme_id, $theme_version, $errors);
+ }
+ }
+ function deactivate()
+ {
+ if (is_callable('theme_deactivate'))
+ {
+ return theme_deactivate($this->theme_id);
+ }
+ }
+ function delete()
+ {
+ if (is_callable('theme_delete'))
+ {
+ return theme_delete($this->theme_id);
+ }
+ }
+}
+
+
+class themes
+{
+ var $fs_themes = array();
+ var $db_themes_by_id = array();
+ var $server_themes = array();
+
+ /**
+ * Initialize $fs_themes and $db_themes_by_id
+ */
+ function __construct()
+ {
+ $this->get_fs_themes();
+
+ foreach ($this->get_db_themes() as $db_theme)
+ {
+ $this->db_themes_by_id[$db_theme['id']] = $db_theme;
+ }
+ }
+
+ /**
+ * Returns the maintain class of a theme
+ * or build a new class with the procedural methods
+ * @param string $theme_id
+ */
+ private static function build_maintain_class($theme_id)
+ {
+ $file_to_include = PHPWG_THEMES_PATH.'/'.$theme_id.'/admin/maintain.inc.php';
+ $classname = $theme_id.'_maintain';
+
+ if (file_exists($file_to_include))
+ {
+ include_once($file_to_include);
+
+ if (class_exists($classname))
+ {
+ return new $classname($theme_id);
+ }
+ }
+
+ return new DummyTheme_maintain($theme_id);
+ }
+
+ /**
+ * Perform requested actions
+ * @param string - action
+ * @param string - theme id
+ * @param array - errors
+ */
+ function perform_action($action, $theme_id)
+ {
+ global $conf;
+
+ if (!$conf['enable_extensions_install'] and 'delete' == $action)
+ {
+ die('Piwigo extensions install/update/delete system is disabled');
+ }
+
+ if (isset($this->db_themes_by_id[$theme_id]))
+ {
+ $crt_db_theme = $this->db_themes_by_id[$theme_id];
+ }
+
+ $theme_maintain = self::build_maintain_class($theme_id);
+
+ $errors = array();
+ $activity_details = array('theme_id'=>$theme_id);
+
+ switch ($action)
+ {
+ case 'activate':
+ if (isset($crt_db_theme))
+ {
+ // the theme is already active
+ break;
+ }
+
+ if ('default' == $theme_id)
+ {
+ // you can't activate the "default" theme
+ break;
+ }
+
+ $missing_parent = $this->missing_parent_theme($theme_id);
+ if (isset($missing_parent))
+ {
+ $errors[] = l10n(
+ 'Impossible to activate this theme, the parent theme is missing: %s',
+ $missing_parent
+ );
+
+ break;
+ }
+
+ if ($this->fs_themes[$theme_id]['mobile']
+ and !empty($conf['mobile_theme'])
+ and $conf['mobile_theme'] != $theme_id)
+ {
+ $errors[] = l10n('You can activate only one mobile theme.');
+ break;
+ }
+
+ $theme_maintain->activate($this->fs_themes[$theme_id]['version'], $errors);
+
+ if (empty($errors))
+ {
+ $query = '
+INSERT INTO '.THEMES_TABLE.'
+ (id, version, name)
+ VALUES(\''.$theme_id.'\',
+ \''.$this->fs_themes[$theme_id]['version'].'\',
+ \''.$this->fs_themes[$theme_id]['name'].'\')
+;';
+ pwg_query($query);
+
+ $activity_details['version'] = $this->fs_themes[$theme_id]['version'];
+
+ if ($this->fs_themes[$theme_id]['mobile'])
+ {
+ conf_update_param('mobile_theme', $theme_id);
+ }
+ }
+ break;
+
+ case 'deactivate':
+ if (!isset($crt_db_theme))
+ {
+ // the theme is already inactive
+ break;
+ }
+
+ // you can't deactivate the last theme
+ if (count($this->db_themes_by_id) <= 1)
+ {
+ $errors[] = l10n('Impossible to deactivate this theme, you need at least one theme.');
+ break;
+ }
+
+ if ($theme_id == get_default_theme())
+ {
+ // find a random theme to replace
+ $new_theme = null;
+
+ $query = '
+SELECT id
+ FROM '.THEMES_TABLE.'
+ WHERE id != \''.$theme_id.'\'
+;';
+ $result = pwg_query($query);
+ if (pwg_db_num_rows($result) == 0)
+ {
+ $new_theme = 'default';
+ }
+ else
+ {
+ list($new_theme) = pwg_db_fetch_row($result);
+ }
+
+ $this->set_default_theme($new_theme);
+ }
+
+ $theme_maintain->deactivate();
+
+ $query = '
+DELETE
+ FROM '.THEMES_TABLE.'
+ WHERE id= \''.$theme_id.'\'
+;';
+ pwg_query($query);
+
+ if ($this->fs_themes[$theme_id]['mobile'])
+ {
+ conf_update_param('mobile_theme', '');
+ }
+ break;
+
+ case 'delete':
+ if (!empty($crt_db_theme))
+ {
+ $errors[] = 'CANNOT DELETE - THEME IS INSTALLED';
+ break;
+ }
+ if (!isset($this->fs_themes[$theme_id]))
+ {
+ // nothing to do here
+ break;
+ }
+
+ $children = $this->get_children_themes($theme_id);
+ if (count($children) > 0)
+ {
+ $errors[] = l10n(
+ 'Impossible to delete this theme. Other themes depends on it: %s',
+ implode(', ', $children)
+ );
+ break;
+ }
+
+ $theme_maintain->delete();
+
+ include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+ deltree(PHPWG_THEMES_PATH.$theme_id, PHPWG_THEMES_PATH . 'trash');
+ break;
+
+ case 'set_default':
+ // first we need to know which users are using the current default theme
+ $this->set_default_theme($theme_id);
+ break;
+ }
+
+ pwg_activity('system', ACTIVITY_SYSTEM_THEME, $action, $activity_details);
+
+ return $errors;
+ }
+
+ function missing_parent_theme($theme_id)
+ {
+ if (!isset($this->fs_themes[$theme_id]['parent']))
+ {
+ return null;
+ }
+
+ $parent = $this->fs_themes[$theme_id]['parent'];
+
+ if ('default' == $parent)
+ {
+ return null;
+ }
+
+ if (!isset($this->fs_themes[$parent]))
+ {
+ return $parent;
+ }
+
+ return $this->missing_parent_theme($parent);
+ }
+
+ function get_children_themes($theme_id)
+ {
+ $children = array();
+
+ foreach ($this->fs_themes as $test_child)
+ {
+ if (isset($test_child['parent']) and $test_child['parent'] == $theme_id)
+ {
+ $children[] = $test_child['name'];
+ }
+ }
+
+ return $children;
+ }
+
+ function set_default_theme($theme_id)
+ {
+ global $conf;
+
+ // first we need to know which users are using the current default theme
+ $default_theme = get_default_theme();
+
+ $query = '
+SELECT
+ user_id
+ FROM '.USER_INFOS_TABLE.'
+ WHERE theme = \''.$default_theme.'\'
+;';
+ $user_ids = array_unique(
+ array_merge(
+ array_from_query($query, 'user_id'),
+ array($conf['guest_id'], $conf['default_user_id'])
+ )
+ );
+
+ // $user_ids can't be empty, at least the default user has the default
+ // theme
+
+ $query = '
+UPDATE '.USER_INFOS_TABLE.'
+ SET theme = \''.$theme_id.'\'
+ WHERE user_id IN ('.implode(',', $user_ids).')
+;';
+ pwg_query($query);
+ }
+
+ function get_db_themes($id='')
+ {
+ $query = '
+SELECT
+ *
+ FROM '.THEMES_TABLE;
+
+ $clauses = array();
+ if (!empty($id))
+ {
+ $clauses[] = 'id = \''.$id.'\'';
+ }
+ if (count($clauses) > 0)
+ {
+ $query .= '
+ WHERE '. implode(' AND ', $clauses);
+ }
+
+ $result = pwg_query($query);
+ $themes = array();
+ while ($row = pwg_db_fetch_assoc($result))
+ {
+ $themes[] = $row;
+ }
+ return $themes;
+ }
+
+
+ /**
+ * Get themes defined in the theme directory
+ */
+ function get_fs_themes()
+ {
+ $dir = opendir(PHPWG_THEMES_PATH);
+
+ while ($file = readdir($dir))
+ {
+ if ($file!='.' and $file!='..')
+ {
+ $path = PHPWG_THEMES_PATH.$file;
+ if (is_dir($path)
+ and preg_match('/^[a-zA-Z0-9-_]+$/', $file)
+ and file_exists($path.'/themeconf.inc.php')
+ )
+ {
+ $theme = array(
+ 'id' => $file,
+ 'name' => $file,
+ 'version' => '0',
+ 'uri' => '',
+ 'description' => '',
+ 'author' => '',
+ 'mobile' => false,
+ );
+ $theme_data = implode('', file($path.'/themeconf.inc.php'));
+ if (preg_match("|Theme Name:\\s*(.+)|", $theme_data, $val))
+ {
+ $theme['name'] = trim( $val[1] );
+ }
+ if (preg_match("|Version:\\s*([\\w.-]+)|", $theme_data, $val))
+ {
+ $theme['version'] = trim($val[1]);
+ }
+ if (preg_match("|Theme URI:\\s*(https?:\\/\\/.+)|", $theme_data, $val))
+ {
+ $theme['uri'] = trim($val[1]);
+ }
+ if ($desc = load_language('description.txt', $path.'/', array('return' => true)))
+ {
+ $theme['description'] = trim($desc);
+ }
+ elseif (preg_match("|Description:\\s*(.+)|", $theme_data, $val))
+ {
+ $theme['description'] = trim($val[1]);
+ }
+ if (preg_match("|Author:\\s*(.+)|", $theme_data, $val))
+ {
+ $theme['author'] = trim($val[1]);
+ }
+ if (preg_match("|Author URI:\\s*(https?:\\/\\/.+)|", $theme_data, $val))
+ {
+ $theme['author uri'] = trim($val[1]);
+ }
+ if (!empty($theme['uri']) and strpos($theme['uri'] , 'extension_view.php?eid='))
+ {
+ list( , $extension) = explode('extension_view.php?eid=', $theme['uri']);
+ if (is_numeric($extension)) $theme['extension'] = $extension;
+ }
+ if (preg_match('/["\']parent["\'][^"\']+["\']([^"\']+)["\']/', $theme_data, $val))
+ {
+ $theme['parent'] = $val[1];
+ }
+ if (preg_match('/["\']activable["\'].*?(true|false)/i', $theme_data, $val))
+ {
+ $theme['activable'] = get_boolean($val[1]);
+ }
+ if (preg_match('/["\']mobile["\'].*?(true|false)/i', $theme_data, $val))
+ {
+ $theme['mobile'] = get_boolean($val[1]);
+ }
+ if (preg_match('/["\']use_standard_pages["\'].*?(true|false)/i', $theme_data, $val))
+ {
+ $theme['use_standard_pages'] = get_boolean($val[1]);
+ }
+
+ // screenshot
+ $screenshot_path = $path.'/screenshot.png';
+ if (file_exists($screenshot_path))
+ {
+ $theme['screenshot'] = $screenshot_path;
+ }
+ else
+ {
+ global $conf;
+ $theme['screenshot'] =
+ PHPWG_ROOT_PATH.'admin/themes/'
+ .userprefs_get_param('admin_theme', 'clear')
+ .'/images/missing_screenshot.png'
+ ;
+ }
+
+ $admin_file = $path.'/admin/admin.inc.php';
+ if (file_exists($admin_file))
+ {
+ $theme['admin_uri'] = get_root_url().'admin.php?page=theme&theme='.$file;
+ }
+
+ // IMPORTANT SECURITY !
+ $theme = array_map('htmlspecialchars', $theme);
+ $this->fs_themes[$file] = $theme;
+ }
+ }
+ }
+ closedir($dir);
+ }
+
+ /**
+ * Sort fs_themes
+ */
+ function sort_fs_themes($order='name')
+ {
+ switch ($order)
+ {
+ case 'name':
+ uasort($this->fs_themes, 'name_compare');
+ break;
+ case 'status':
+ $this->sort_themes_by_state();
+ break;
+ case 'author':
+ uasort($this->fs_themes, array($this, 'theme_author_compare'));
+ break;
+ case 'id':
+ uksort($this->fs_themes, 'strcasecmp');
+ break;
+ }
+ }
+
+ /**
+ * Retrieve PEM server datas to $server_themes
+ */
+ function get_server_themes($new=false)
+ {
+ global $user, $conf;
+
+ $get_data = array(
+ 'category_id' => $conf['pem_themes_category'],
+ 'format' => 'php',
+ );
+
+ // Retrieve PEM versions
+ $version = PHPWG_VERSION;
+ $versions_to_check = array();
+ $url = PEM_URL . '/api/get_version_list.php';
+ if (fetchRemote($url, $result, $get_data) and $pem_versions = @unserialize($result))
+ {
+ if (!preg_match('/^\d+\.\d+\.\d+$/', $version))
+ {
+ $version = $pem_versions[0]['name'];
+ }
+ $branch = get_branch_from_version($version);
+ foreach ($pem_versions as $pem_version)
+ {
+ if (strpos($pem_version['name'], $branch) === 0)
+ {
+ $versions_to_check[] = $pem_version['id'];
+ }
+ }
+ }
+ if (empty($versions_to_check))
+ {
+ return false;
+ }
+
+ // Themes to check
+ $themes_to_check = array();
+ foreach($this->fs_themes as $fs_theme)
+ {
+ if (isset($fs_theme['extension']))
+ {
+ $themes_to_check[] = $fs_theme['extension'];
+ }
+ }
+
+ // Retrieve PEM themes infos
+ $url = PEM_URL . '/api/get_revision_list-next.php';
+ $get_data = array_merge($get_data, array(
+ 'last_revision_only' => 'true',
+ 'version' => implode(',', $versions_to_check),
+ 'lang' => substr($user['language'], 0, 2),
+ 'get_nb_downloads' => 'true',
+ )
+ );
+
+ if (!empty($themes_to_check))
+ {
+ if ($new)
+ {
+ $get_data['extension_exclude'] = implode(',', $themes_to_check);
+ }
+ else
+ {
+ $get_data['extension_include'] = implode(',', $themes_to_check);
+ }
+ }
+ if (fetchRemote($url, $result, $get_data))
+ {
+ $pem_themes = @unserialize($result);
+ if (!is_array($pem_themes))
+ {
+ return false;
+ }
+ foreach ($pem_themes as $theme)
+ {
+ $this->server_themes[$theme['extension_id']] = $theme;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Sort $server_themes
+ */
+ function sort_server_themes($order='date')
+ {
+ switch ($order)
+ {
+ case 'date':
+ krsort($this->server_themes);
+ break;
+ case 'revision':
+ usort($this->server_themes, array($this, 'extension_revision_compare'));
+ break;
+ case 'name':
+ uasort($this->server_themes, array($this, 'extension_name_compare'));
+ break;
+ case 'author':
+ uasort($this->server_themes, array($this, 'extension_author_compare'));
+ break;
+ case 'downloads':
+ usort($this->server_themes, array($this, 'extension_downloads_compare'));
+ break;
+ }
+ }
+
+ /**
+ * Extract theme files from archive
+ *
+ * @param string - install or upgrade
+ * @param string - remote revision identifier (numeric)
+ * @param string - theme id or extension id
+ */
+ function extract_theme_files($action, $revision, $dest, &$theme_id=null)
+ {
+ global $logger;
+
+ if ($archive = tempnam( PHPWG_THEMES_PATH, 'zip'))
+ {
+ $url = PEM_URL . '/download.php';
+ $get_data = array(
+ 'rid' => $revision,
+ 'origin' => 'piwigo_'.$action,
+ );
+
+ if ($handle = @fopen($archive, 'wb') and fetchRemote($url, $handle, $get_data))
+ {
+ fclose($handle);
+ include_once(PHPWG_ROOT_PATH.'admin/include/pclzip.lib.php');
+ $zip = new PclZip($archive);
+ if ($list = $zip->listContent())
+ {
+ foreach ($list as $file)
+ {
+ // we search main.inc.php in archive
+ if (basename($file['filename']) == 'themeconf.inc.php'
+ and (!isset($main_filepath)
+ or strlen($file['filename']) < strlen($main_filepath)))
+ {
+ $main_filepath = $file['filename'];
+ }
+ }
+
+ $logger->debug(__FUNCTION__.', $main_filepath = '.$main_filepath);
+
+ if (isset($main_filepath))
+ {
+ $root = dirname($main_filepath); // main.inc.php path in archive
+ if ($action == 'upgrade')
+ {
+ $theme_id = $dest;
+ }
+ else
+ {
+ $theme_id = ($root == '.' ? 'extension_' . $dest : basename($root));
+ }
+ $extract_path = PHPWG_THEMES_PATH . $theme_id;
+ $logger->debug(__FUNCTION__.', $extract_path = '.$extract_path);
+
+ if (
+ $result = $zip->extract(
+ PCLZIP_OPT_PATH, $extract_path,
+ PCLZIP_OPT_REMOVE_PATH, $root,
+ PCLZIP_OPT_REPLACE_NEWER
+ )
+ )
+ {
+ foreach ($result as $file)
+ {
+ if ($file['stored_filename'] == $main_filepath)
+ {
+ $status = $file['status'];
+ break;
+ }
+ }
+ if (file_exists($extract_path.'/obsolete.list')
+ and $old_files = file($extract_path.'/obsolete.list', FILE_IGNORE_NEW_LINES)
+ and !empty($old_files))
+ {
+ $old_files[] = 'obsolete.list';
+
+ $logger->debug(__FUNCTION__.', $old_files = {'.join('},{', $old_files).'}');
+
+ $extract_path_realpath = realpath($extract_path);
+
+ foreach($old_files as $old_file)
+ {
+ $old_file = trim($old_file);
+ $old_file = trim($old_file, '/'); // prevent path starting with a "/"
+
+ if (empty($old_file)) // empty here means the extension itself
+ {
+ continue;
+ }
+
+ $path = $extract_path.'/'.$old_file;
+
+ // make sure the obsolete file is withing the extension directory, prevent traversal path
+ $realpath = realpath($path);
+ if ($realpath === false or strpos($realpath, $extract_path_realpath) !== 0)
+ {
+ continue;
+ }
+
+ $logger->debug(__FUNCTION__.', to delete = '.$path);
+
+ if (is_file($path))
+ {
+ @unlink($path);
+ }
+ elseif (is_dir($path))
+ {
+ deltree($path, PHPWG_THEMES_PATH . 'trash');
+ }
+ }
+ }
+ }
+ else $status = 'extract_error';
+ }
+ else $status = 'archive_error';
+ }
+ else $status = 'archive_error';
+ }
+ else $status = 'dl_archive_error';
+ }
+ else $status = 'temp_path_error';
+
+ @unlink($archive);
+ return $status;
+ }
+
+ /**
+ * Sort functions
+ */
+ function extension_revision_compare($a, $b)
+ {
+ if ($a['revision_date'] < $b['revision_date']) return 1;
+ else return -1;
+ }
+
+ function extension_name_compare($a, $b)
+ {
+ return strcmp(strtolower($a['extension_name']), strtolower($b['extension_name']));
+ }
+
+ function extension_author_compare($a, $b)
+ {
+ $r = strcasecmp($a['author_name'], $b['author_name']);
+ if ($r == 0) return $this->extension_name_compare($a, $b);
+ else return $r;
+ }
+
+ function theme_author_compare($a, $b)
+ {
+ $r = strcasecmp($a['author'], $b['author']);
+ if ($r == 0) return name_compare($a, $b);
+ else return $r;
+ }
+
+ function extension_downloads_compare($a, $b)
+ {
+ if ($a['extension_nb_downloads'] < $b['extension_nb_downloads']) return 1;
+ else return -1;
+ }
+
+ function sort_themes_by_state()
+ {
+ uasort($this->fs_themes, 'name_compare');
+
+ $active_themes = array();
+ $inactive_themes = array();
+ $not_installed = array();
+
+ foreach($this->fs_themes as $theme_id => $theme)
+ {
+ if (isset($this->db_themes_by_id[$theme_id]))
+ {
+ $this->db_themes_by_id[$theme_id]['state'] == 'active' ?
+ $active_themes[$theme_id] = $theme : $inactive_themes[$theme_id] = $theme;
+ }
+ else
+ {
+ $not_installed[$theme_id] = $theme;
+ }
+ }
+ $this->fs_themes = $active_themes + $inactive_themes + $not_installed;
+ }
+
+}
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/include/updates.class.php b/Piwingo/piwigo-data/piwigo/admin/include/updates.class.php
new file mode 100644
index 0000000..03e767c
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/include/updates.class.php
@@ -0,0 +1,668 @@
+types = array('plugins', 'themes', 'languages');
+
+ if (in_array($page, $this->types))
+ {
+ $this->types = array($page);
+ }
+ $this->default_themes = array('modus', 'elegant', 'smartpocket');
+ $this->default_plugins = array('AdminTools', 'TakeATour', 'language_switch', 'LocalFilesEditor');
+
+ foreach ($this->types as $type)
+ {
+ include_once(PHPWG_ROOT_PATH.'admin/include/'.$type.'.class.php');
+ $this->$type = new $type();
+ }
+ }
+
+ static function check_piwigo_upgrade()
+ {
+ $_SESSION['need_update'.PHPWG_VERSION] = null;
+
+ if (preg_match('/(\d+\.\d+)\.(\d+)/', PHPWG_VERSION, $matches)
+ and @fetchRemote(PHPWG_URL.'/download/all_versions.php?rand='.md5(uniqid(rand(), true)), $result))
+ {
+ $all_versions = @explode("\n", $result);
+ $new_version = trim($all_versions[0]);
+ $_SESSION['need_update'.PHPWG_VERSION] = version_compare(PHPWG_VERSION, $new_version, '<');
+ }
+ }
+
+ /**
+ * finds new versions of Piwigo on Piwigo.org.
+ *
+ * @since 2.9
+ * @return array (
+ * 'piwigo.org-checked' => has piwigo.org been checked?,
+ * 'is_dev' => are we on a dev version?,
+ * 'minor_version' => new minor version available,
+ * 'major_version' => new major version available,
+ * )
+ */
+ function get_piwigo_new_versions()
+ {
+ global $conf;
+
+ $new_versions = array(
+ 'piwigo.org-checked' => false,
+ 'is_dev' => true,
+ );
+
+ list($env, $build_version) = get_container_info();
+ if (preg_match('/^(\d+\.\d+)\.(\d+)$/', PHPWG_VERSION))
+ {
+ $new_versions['is_dev'] = false;
+ $actual_branch = get_branch_from_version(('Official' === $env)
+ ? substr($build_version, 0, -1)
+ : PHPWG_VERSION
+ );
+
+ $url = PHPWG_URL.'/download/all_versions.php';
+ $url.= '?rand='.md5(uniqid(rand(), true)); // Avoid server cache
+ $url .= ('Official' === $env) ? '&docker' : '&show_requirements'; // Check docker version if in container
+ $url.= '&origin_hash='.sha1($conf['secret_key'].get_absolute_root_url());
+
+ if (@fetchRemote($url, $result)
+ and $all_versions = @explode("\n", $result)
+ and is_array($all_versions))
+ {
+ $new_versions['piwigo.org-checked'] = true;
+ $last_version = trim($all_versions[0]);
+ if ('Official' === $env)
+ {
+ if ($this->container_version_compare($build_version, $last_version))
+ {
+ $last_branch = get_branch_from_version(substr($last_version, 0, -1));
+ if ($last_branch == $actual_branch)
+ {
+ $new_versions['minor'] = $last_version;
+ }
+ else
+ {
+ $new_versions['major'] = $last_version;
+ foreach ($all_versions as $version)
+ {
+ $branch = get_branch_from_version(substr($version, 0, -1));
+ if ($branch == $actual_branch)
+ {
+ if ($this->container_version_compare($build_version, $version))
+ {
+ $new_versions['minor'] = $version;
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ list($last_version_number, $last_version_php) = explode('/', trim($all_versions[0]));
+
+ if (version_compare(PHPWG_VERSION, $last_version_number, '<'))
+ {
+ $last_branch = get_branch_from_version($last_version_number);
+
+ if ($last_branch == $actual_branch)
+ {
+ $new_versions['minor'] = $last_version_number;
+ $new_versions['minor_php'] = $last_version_php;
+ }
+ else
+ {
+ $new_versions['major'] = $last_version_number;
+ $new_versions['major_php'] = $last_version_php;
+
+ // Check if new version exists in same branch
+ foreach ($all_versions as $version)
+ {
+ list($version_number, $version_php) = explode('/', trim($version));
+ $branch = get_branch_from_version($version_number);
+
+ if ($branch == $actual_branch)
+ {
+ if (version_compare(PHPWG_VERSION, $version_number, '<'))
+ {
+ $new_versions['minor'] = $version_number;
+ $new_versions['minor_php'] = $version_php;
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return $new_versions;
+ }
+
+ /**
+ * Checks for new versions of Piwigo. Notify webmasters if new versions are available, but not too often, see
+ * $conf['update_notify_reminder_period'] parameter.
+ *
+ * @since 2.9
+ */
+ function notify_piwigo_new_versions()
+ {
+ global $conf;
+
+ if (!pwg_is_dbconf_writeable())
+ {
+ return;
+ }
+
+ $new_versions = $this->get_piwigo_new_versions();
+ conf_update_param('update_notify_last_check', date('c'));
+
+ if ($new_versions['is_dev'])
+ {
+ return;
+ }
+
+ $new_versions_string = join(
+ ' & ',
+ array_intersect_key(
+ $new_versions,
+ array_fill_keys(array('minor', 'major'), 1)
+ )
+ );
+
+ if (empty($new_versions_string))
+ {
+ return;
+ }
+
+ // In which case should we notify?
+ // 1. never notified
+ // 2. new versions
+ // 3. no new versions but reminder needed
+
+ $notify = false;
+ if (!isset($conf['update_notify_last_notification']))
+ {
+ $notify = true;
+ }
+ else
+ {
+ $conf['update_notify_last_notification'] = safe_unserialize($conf['update_notify_last_notification']);
+ $last_notification = $conf['update_notify_last_notification']['notified_on'];
+
+ if ($new_versions_string != $conf['update_notify_last_notification']['version'])
+ {
+ $notify = true;
+ }
+ elseif (
+ $conf['update_notify_reminder_period'] > 0
+ and strtotime($last_notification) < strtotime($conf['update_notify_reminder_period'].' seconds ago')
+ )
+ {
+ $notify = true;
+ }
+ }
+
+ if ($notify)
+ {
+ // send email
+ include_once(PHPWG_ROOT_PATH.'include/functions_mail.inc.php');
+
+ switch_lang_to(get_default_language());
+
+ $content = l10n('Hello,');
+ $content.= "\n\n".l10n(
+ 'Time has come to update your Piwigo with version %s, go to %s',
+ $new_versions_string,
+ get_absolute_root_url().'admin.php?page=updates'
+ );
+ $content.= "\n\n".l10n('It only takes a few clicks.');
+ $content.= "\n\n".l10n('Running on an up-to-date Piwigo is important for security.');
+
+ pwg_mail_admins(
+ array(
+ 'subject' => l10n('Piwigo %s is available, please update', $new_versions_string),
+ 'content' => $content,
+ 'content_format' => 'text/plain',
+ ),
+ array(
+ 'filename' => 'notification_admin',
+ ),
+ false, // do not exclude current user
+ true // only webmasters
+ );
+
+ switch_lang_back();
+
+ // save notify
+ conf_update_param(
+ 'update_notify_last_notification',
+ array(
+ 'version' => $new_versions_string,
+ 'notified_on' => date('c'),
+ )
+ );
+ }
+ }
+
+ function get_server_extensions($version=PHPWG_VERSION)
+ {
+ global $user;
+
+ $get_data = array(
+ 'format' => 'php',
+ );
+
+ // Retrieve PEM versions
+ $versions_to_check = array();
+ $url = PEM_URL . '/api/get_version_list.php';
+ if (fetchRemote($url, $result, $get_data) and $pem_versions = @unserialize($result))
+ {
+ if (!preg_match('/^\d+\.\d+\.\d+$/', $version))
+ {
+ $version = $pem_versions[0]['name'];
+ }
+ $branch = get_branch_from_version($version);
+ foreach ($pem_versions as $pem_version)
+ {
+ if (strpos($pem_version['name'], $branch) === 0)
+ {
+ $versions_to_check[] = $pem_version['id'];
+ }
+ }
+ }
+ if (empty($versions_to_check))
+ {
+ return false;
+ }
+
+ // Extensions to check
+ $ext_to_check = array();
+ foreach ($this->types as $type)
+ {
+ $fs = 'fs_'.$type;
+ foreach ($this->$type->$fs as $ext)
+ {
+ if (isset($ext['extension']))
+ {
+ $ext_to_check[$ext['extension']] = $type;
+ }
+ }
+ }
+
+ // Retrieve PEM plugins infos
+ $url = PEM_URL . '/api/get_revision_list.php';
+ $get_data = array_merge($get_data, array(
+ 'last_revision_only' => 'true',
+ 'version' => implode(',', $versions_to_check),
+ 'lang' => substr($user['language'], 0, 2),
+ 'get_nb_downloads' => 'true',
+ )
+ );
+
+ $post_data = array();
+ if (!empty($ext_to_check))
+ {
+ $post_data['extension_include'] = implode(',', array_keys($ext_to_check));
+ }
+
+ if (fetchRemote($url, $result, $get_data, $post_data))
+ {
+ $pem_exts = @unserialize($result);
+ if (!is_array($pem_exts))
+ {
+ return false;
+ }
+
+ $servers = array();
+
+ foreach ($pem_exts as $ext)
+ {
+ if (isset($ext_to_check[$ext['extension_id']]))
+ {
+ $type = $ext_to_check[$ext['extension_id']];
+
+ if (!isset($servers[$type]))
+ {
+ $servers[$type] = array();
+ }
+
+ $servers[$type][ $ext['extension_id'] ] = $ext;
+
+ unset($ext_to_check[$ext['extension_id']]);
+ }
+ }
+
+ foreach ($servers as $server_type => $extension_list)
+ {
+ $server_string = 'server_'.$server_type;
+
+ $this->$server_type->$server_string = $extension_list;
+ }
+
+ $this->check_missing_extensions($ext_to_check);
+ return true;
+ }
+ return false;
+ }
+
+ // Check all extensions upgrades
+ function check_extensions()
+ {
+ global $conf;
+
+ if (!$this->get_server_extensions())
+ {
+ return false;
+ }
+
+ $_SESSION['extensions_need_update'] = array();
+
+ foreach ($this->types as $type)
+ {
+ $fs = 'fs_'.$type;
+ $server = 'server_'.$type;
+ $server_ext = $this->$type->$server;
+ $fs_ext = $this->$type->$fs;
+
+ $ignore_list = array();
+ $need_upgrade = array();
+
+ foreach($fs_ext as $ext_id => $fs_ext)
+ {
+ if (isset($fs_ext['extension']) and isset($server_ext[$fs_ext['extension']]))
+ {
+ $ext_info = $server_ext[$fs_ext['extension']];
+
+ if (!safe_version_compare($fs_ext['version'], $ext_info['revision_name'], '>='))
+ {
+ if (in_array($ext_id, $conf['updates_ignored'][$type]))
+ {
+ $ignore_list[] = $ext_id;
+ }
+ else
+ {
+ $_SESSION['extensions_need_update'][$type][$ext_id] = $ext_info['revision_name'];
+ }
+ }
+ }
+ }
+ $conf['updates_ignored'][$type] = $ignore_list;
+ }
+ conf_update_param('updates_ignored', pwg_db_real_escape_string(serialize($conf['updates_ignored'])));
+ }
+
+ // Check if extension have been upgraded since last check
+ function check_updated_extensions()
+ {
+ foreach ($this->types as $type)
+ {
+ if (!empty($_SESSION['extensions_need_update'][$type]))
+ {
+ $fs = 'fs_'.$type;
+ foreach($this->$type->$fs as $ext_id => $fs_ext)
+ {
+ if (isset($_SESSION['extensions_need_update'][$type][$ext_id])
+ and safe_version_compare($fs_ext['version'], $_SESSION['extensions_need_update'][$type][$ext_id], '>='))
+ {
+ // Extension have been upgraded
+ $this->check_extensions();
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ function check_missing_extensions($missing)
+ {
+ foreach ($missing as $id => $type)
+ {
+ $fs = 'fs_'.$type;
+ $default = 'default_'.$type;
+ foreach ($this->$type->$fs as $ext_id => $ext)
+ {
+ if (isset($ext['extension']) and $id == $ext['extension']
+ and !in_array($ext_id, $this->$default)
+ and !in_array($ext['extension'], $this->merged_extensions))
+ {
+ $this->missing[$type][] = $ext;
+ break;
+ }
+ }
+ }
+ }
+
+ function get_merged_extensions($version)
+ {
+ if (fetchRemote($this->merged_extension_url, $result))
+ {
+ $rows = explode("\n", $result);
+ foreach ($rows as $row)
+ {
+ if (preg_match('/^(\d+\.\d+): *(.*)$/', $row, $match))
+ {
+ if (version_compare($version, $match[1], '>='))
+ {
+ $extensions = explode(',', trim($match[2]));
+ $this->merged_extensions = array_merge($this->merged_extensions, $extensions);
+ }
+ }
+ }
+ }
+ }
+
+ static function process_obsolete_list($file)
+ {
+ if (file_exists(PHPWG_ROOT_PATH.$file)
+ and $old_files = file(PHPWG_ROOT_PATH.$file, FILE_IGNORE_NEW_LINES)
+ and !empty($old_files))
+ {
+ $old_files[] = $file;
+ foreach($old_files as $old_file)
+ {
+ $path = PHPWG_ROOT_PATH.$old_file;
+ if (is_file($path))
+ {
+ @unlink($path);
+ }
+ elseif (is_dir($path))
+ {
+ deltree($path, PHPWG_ROOT_PATH.'_trash');
+ }
+ }
+ }
+ }
+
+ static function upgrade_to($upgrade_to, &$step, $check_current_version=true)
+ {
+ global $page, $conf, $template;
+
+ if ($check_current_version and !version_compare($upgrade_to, PHPWG_VERSION, '>'))
+ {
+ // TODO why redirect to a plugin page? maybe a remaining code from when
+ // the update system was provided as a plugin?
+ redirect(get_root_url().'admin.php?page=plugin-'.basename(dirname(__FILE__)));
+ }
+
+ $obsolete_list = null;
+
+ if ($step == 2)
+ {
+ $code = get_branch_from_version(PHPWG_VERSION).'.x_to_'.$upgrade_to;
+ $dl_code = str_replace(array('.', '_'), '', $code);
+ $remove_path = $code;
+ // no longer try to delete files on a minor upgrade
+ // $obsolete_list = 'obsolete.list';
+ }
+ else
+ {
+ $code = $upgrade_to;
+ $dl_code = $code;
+ $remove_path = version_compare($code, '2.0.8', '>=') ? 'piwigo' : 'piwigo-'.$code;
+ $obsolete_list = PHPWG_ROOT_PATH.'install/obsolete.list';
+ }
+
+ if (empty($page['errors']))
+ {
+ $path = PHPWG_ROOT_PATH.$conf['data_location'].'update';
+ $filename = $path.'/'.$code.'.zip';
+ @mkgetdir($path);
+
+ $chunk_num = 0;
+ $end = false;
+ $zip = @fopen($filename, 'w');
+
+ while (!$end)
+ {
+ $chunk_num++;
+ if (@fetchRemote(PHPWG_URL.'/download/dlcounter.php?code='.$dl_code.'&chunk_num='.$chunk_num, $result)
+ and $input = @unserialize($result))
+ {
+ if (0 == $input['remaining'])
+ {
+ $end = true;
+ }
+ @fwrite($zip, base64_decode($input['data']));
+ }
+ else
+ {
+ $end = true;
+ }
+ }
+ @fclose($zip);
+
+ if (@filesize($filename))
+ {
+ $zip = new PclZip($filename);
+ if ($result = $zip->extract(PCLZIP_OPT_PATH, PHPWG_ROOT_PATH,
+ PCLZIP_OPT_REMOVE_PATH, $remove_path,
+ PCLZIP_OPT_SET_CHMOD, 0755,
+ PCLZIP_OPT_REPLACE_NEWER))
+ {
+ //Check if all files were extracted
+ $error = '';
+ foreach($result as $extract)
+ {
+ if (!in_array($extract['status'], array('ok', 'filtered', 'already_a_directory')))
+ {
+ // Try to change chmod and extract
+ if (@chmod(PHPWG_ROOT_PATH.$extract['filename'], 0777)
+ and ($res = $zip->extract(PCLZIP_OPT_BY_NAME, $remove_path.'/'.$extract['filename'],
+ PCLZIP_OPT_PATH, PHPWG_ROOT_PATH,
+ PCLZIP_OPT_REMOVE_PATH, $remove_path,
+ PCLZIP_OPT_SET_CHMOD, 0755,
+ PCLZIP_OPT_REPLACE_NEWER))
+ and isset($res[0]['status'])
+ and $res[0]['status'] == 'ok')
+ {
+ continue;
+ }
+ else
+ {
+ $error .= $extract['filename'].': '.$extract['status']."\n";
+ }
+ }
+ }
+
+ if (empty($error))
+ {
+ if (!empty($obsolete_list))
+ {
+ self::process_obsolete_list($obsolete_list);
+ }
+
+ deltree(PHPWG_ROOT_PATH.$conf['data_location'].'update');
+ invalidate_user_cache(true);
+ conf_update_param('piwigo_installed_version', $upgrade_to);
+ pwg_activity('system', ACTIVITY_SYSTEM_CORE, 'update', array('from_version'=>PHPWG_VERSION, 'to_version'=>$upgrade_to));
+
+ if ($step == 2)
+ {
+ // only delete compiled templates on minor update. Doing this on
+ // a major update might even encounter fatal error if Smarty
+ // changes. Anyway, a compiled template purge will be performed
+ // by upgrade.php
+ $template->delete_compiled_templates();
+ conf_delete_param('fs_quick_check_last_check');
+
+ $page['infos'][] = l10n('Update Complete');
+ $page['infos'][] = $upgrade_to;
+ $page['updated_version'] = $upgrade_to;
+ $step = -1;
+ }
+ else
+ {
+ redirect(PHPWG_ROOT_PATH.'upgrade.php?now=');
+ }
+ }
+ else
+ {
+ file_put_contents(PHPWG_ROOT_PATH.$conf['data_location'].'update/log_error.txt', $error);
+
+ $page['errors'][] = l10n(
+ 'An error has occured during extract. Please check files permissions of your piwigo installation.
Click here to show log error.',
+ get_root_url().$conf['data_location'].'update/log_error.txt'
+ );
+ }
+ }
+ else
+ {
+ deltree(PHPWG_ROOT_PATH.$conf['data_location'].'update');
+ $page['errors'][] = l10n('An error has occured during upgrade.');
+ }
+ }
+ else
+ {
+ $page['errors'][] = l10n('Piwigo cannot retrieve upgrade file from server');
+ }
+ }
+ }
+
+ // Compare version number with a letter suffix
+ // Similar to version_compare with "<" sign
+ function container_version_compare($v1,$v2)
+ {
+ // Split 16.2.0d into "16.2.0" as semantic_ver and "d" as sub_ver
+ $v1_semantic_ver = substr($v1, 0, -1);
+ $v1_sub_ver = substr($v1, -1);
+ $v2_semantic_ver = substr($v2, 0, -1);
+ $v2_sub_ver = substr($v2, -1);
+
+ $res = version_compare($v1_semantic_ver, $v2_semantic_ver);
+
+ // Return for any
+ if ($res === 0)
+ {
+ return strcmp($v1_sub_ver, $v2_sub_ver) < 0;
+ }
+
+ return $res;
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/include/user_tabs.inc.php b/Piwingo/piwigo-data/piwigo/admin/include/user_tabs.inc.php
new file mode 100644
index 0000000..b83b9b5
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/include/user_tabs.inc.php
@@ -0,0 +1,18 @@
+set_id('users');
+$tabsheet->select($page['tab']);
+$tabsheet->assign();
+
+?>
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/index.php b/Piwingo/piwigo-data/piwigo/admin/index.php
new file mode 100644
index 0000000..58ea04e
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/index.php
@@ -0,0 +1,15 @@
+
diff --git a/Piwingo/piwigo-data/piwigo/admin/intro.php b/Piwingo/piwigo-data/piwigo/admin/intro.php
new file mode 100644
index 0000000..356f432
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/intro.php
@@ -0,0 +1,472 @@
+set_id('admin_home');
+$tabsheet->select('');
+$tabsheet->assign();
+
+// +-----------------------------------------------------------------------+
+// | actions |
+// +-----------------------------------------------------------------------+
+
+if (isset($page['nb_pending_comments']))
+{
+ $message = l10n('User comments').' ';
+ $message.= '';
+ $message.= l10n('%d waiting for validation', $page['nb_pending_comments']);
+ $message.= ' ';
+
+ $page['messages'][] = $message;
+}
+
+// any orphan photo?
+$nb_orphans = $page['nb_orphans']; // already calculated in admin.php
+
+if ($page['nb_photos_total'] >= 100000) // but has not been calculated on a big gallery, so force it now
+{
+ $nb_orphans = count_orphans();
+}
+
+if ($nb_orphans > 0)
+{
+ $orphans_url = PHPWG_ROOT_PATH.'admin.php?page=batch_manager&filter=prefilter-no_album';
+
+ $message = '';
+ $message.= l10n('Orphans').'';
+ $message.= '';
+
+ $page['warnings'][] = $message;
+}
+
+// locked album ?
+$query = '
+SELECT COUNT(*)
+ FROM '.CATEGORIES_TABLE.'
+ WHERE visible =\'false\'
+;';
+list($locked_album) = pwg_db_fetch_row(pwg_query($query));
+if ($locked_album > 0)
+{
+ $locked_album_url = PHPWG_ROOT_PATH.'admin.php?page=cat_options§ion=visible';
+
+ $message = '';
+ $message.= l10n('Locked album').'';
+ $message.= '';
+
+ $page['warnings'][] = $message;
+}
+
+fs_quick_check();
+
+// +-----------------------------------------------------------------------+
+// | template init |
+// +-----------------------------------------------------------------------+
+
+$template->set_filenames(array('intro' => 'intro.tpl'));
+
+if ($conf['show_newsletter_subscription'] and userprefs_get_param('show_newsletter_subscription', true)) {
+ $query = '
+ SELECT registration_date
+ FROM '.USER_INFOS_TABLE.'
+ WHERE registration_date IS NOT NULL
+ ORDER BY user_id ASC
+ LIMIT 1
+ ;';
+ list($register_date) = pwg_db_fetch_row(pwg_query($query));
+
+ $query = '
+ SELECT COUNT(*)
+ FROM '.CATEGORIES_TABLE.'
+ ;';
+ list($nb_cats) = pwg_db_fetch_row(pwg_query($query));
+
+ $query = '
+ SELECT COUNT(*)
+ FROM '.IMAGES_TABLE.'
+ ;';
+ list($nb_images) = pwg_db_fetch_row(pwg_query($query));
+
+ include_once(PHPWG_ROOT_PATH.'include/mdetect.php');
+ $uagent_obj = new uagent_info();
+ // To see the newsletter promote, the account must have 2 weeks ancient, 3 albums created and 30 photos uploaded
+
+ if (!$uagent_obj->DetectIos() and strtotime($register_date) < strtotime('2 weeks ago') and $nb_cats >= 3 and $nb_images >= 30){
+ $template->assign(
+ array(
+ 'EMAIL' => $user['email'],
+ 'SUBSCRIBE_BASE_URL' => get_newsletter_subscribe_base_url($user['language']),
+ 'OLD_NEWSLETTERS_URL' => get_old_newsletters_base_url($user['language']),
+ )
+ );
+ }
+
+}
+
+
+$stats = get_pwg_general_statitics();
+
+$du_decimals = 1;
+$du_gb = $stats['disk_usage']/(1024*1024);
+if ($du_gb > 100)
+{
+ $du_decimals = 0;
+}
+
+$template->assign(
+ array(
+ 'NB_PHOTOS' => $stats['nb_photos'],
+ 'NB_ALBUMS' => $stats['nb_categories'],
+ 'NB_TAGS' => $stats['nb_tags'],
+ 'NB_IMAGE_TAG' => $stats['nb_image_tag'],
+ 'NB_USERS' => $stats['nb_users'],
+ 'NB_GROUPS' => $stats['nb_groups'],
+ 'NB_RATES' => $stats['nb_rates'],
+ 'NB_VIEWS' => number_format_human_readable($stats['nb_views']),
+ 'NB_PLUGINS' => count($pwg_loaded_plugins),
+ 'STORAGE_USED' => str_replace(' ', ' ', l10n('%sGB', number_format($du_gb, $du_decimals))),
+ 'U_QUICK_SYNC' => PHPWG_ROOT_PATH.'admin.php?page=site_update&site=1&quick_sync=1&pwg_token='.get_pwg_token(),
+ 'CHECK_FOR_UPDATES' => $conf['dashboard_check_for_updates'],
+ )
+ );
+
+if ($conf['activate_comments'])
+{
+ $query = '
+SELECT COUNT(*)
+ FROM '.COMMENTS_TABLE.'
+;';
+ list($nb_comments) = pwg_db_fetch_row(pwg_query($query));
+ $template->assign('NB_COMMENTS', $nb_comments);
+} else {
+ $template->assign('NB_COMMENTS', 0);
+}
+
+if ($conf['show_piwigo_latest_news'])
+{
+ $latest_news = get_piwigo_news();
+
+ if (isset($latest_news['id']) and $latest_news['posted_on'] > time()-60*60*24*30)
+ {
+ $page['messages'][] = sprintf(
+ '%s %s',
+ l10n('Latest Piwigo news'),
+ $latest_news['url'],
+ time_since($latest_news['posted_on'], 'year').' ('.$latest_news['posted'].')',
+ $latest_news['subject']
+ );
+ }
+}
+
+trigger_notify('loc_end_intro');
+
+// +-----------------------------------------------------------------------+
+// | get activity data |
+// +-----------------------------------------------------------------------+
+
+$nb_weeks = $conf['dashboard_activity_nb_weeks'];
+
+//Count mondays
+$mondays = 0;
+//Get mondays number for the chart legend
+$week_number = array();
+//Array for sorting days in circle size
+$temp_data = array();
+
+$activity_last_weeks = array();
+$date = new DateTime();
+
+//Get data from $nb_weeks last weeks
+while ($mondays < $nb_weeks)
+{
+ if ($date->format('D') == 'Mon')
+ {
+ $week_number[] = $date->format('W');
+ $mondays += 1;
+ }
+
+ $date->sub(new DateInterval('P1D'));
+}
+
+$week_number = array_reverse($week_number);
+$date_string = $date->format('Y-m-d');
+
+if (!isset($_SESSION['cache_activity_last_weeks']) or $_SESSION['cache_activity_last_weeks']['calculated_on'] < strtotime('5 minutes ago'))
+{
+ $start_time = get_moment();
+
+ $query = '
+ SELECT
+ DATE_FORMAT(occured_on , \'%Y-%m-%d\') AS activity_day,
+ object,
+ action,
+ COUNT(*) AS activity_counter
+ FROM `'.ACTIVITY_TABLE.'`
+ WHERE occured_on >= \''.$date_string.'\'
+ GROUP BY activity_day, object, action
+ ;';
+ $activity_actions = query2array($query);
+
+ foreach ($activity_actions as $action)
+ {
+ // set the time to 12:00 (midday) so that it doesn't goes to previous/next day due to timezone offset
+ $day_date = new DateTime($action['activity_day'].' 12:00:00');
+
+ $week = 0;
+ for ($i=0; $i < $nb_weeks; $i++)
+ {
+ if ($week_number[$i] == $day_date->format('W'))
+ {
+ $week = $i;
+ }
+ }
+ $day_nb = $day_date->format('N');
+
+ @$activity_last_weeks[$week][$day_nb]['details'][ucfirst($action['object'])][ucfirst($action['action'])] = $action['activity_counter'];
+ @$activity_last_weeks[$week][$day_nb]['number'] += $action['activity_counter'];
+ @$activity_last_weeks[$week][$day_nb]['date'] = format_date($day_date->getTimestamp());
+ }
+
+ $logger->debug('[admin/intro::'.__LINE__.'] recent activity calculated in '.get_elapsed_time($start_time, get_moment()));
+
+ $_SESSION['cache_activity_last_weeks'] = array(
+ 'calculated_on' => time(),
+ 'data' => $activity_last_weeks,
+ );
+}
+
+$activity_last_weeks = $_SESSION['cache_activity_last_weeks']['data'];
+
+
+foreach($activity_last_weeks as $week => $i)
+{
+ foreach($i as $day => $j)
+ {
+ $details = $j['details'];
+ ksort($details);
+ $activity_last_weeks[$week][$day]['details'] = $details;
+ if ($j['number'] > 0)
+ {
+ $temp_data[] = array('x' => $j['number'], 'd'=>$day, 'w'=>$week);
+ }
+ }
+}
+
+// Algorithm to sort days in circle size :
+// * Get the difference between sorted numbers of activity per day (only not null numbers)
+// * Split days max $circle_sizes time on the biggest difference (but not below 120%)
+// * Set the sizes according to the groups created
+
+//Function to sort days by number of activity
+function cmp_day($a, $b)
+{
+ if ($a['x'] == $b['x'])
+ {
+ return 0;
+ }
+ return ($a['x'] < $b['x']) ? -1 : 1;
+}
+
+usort($temp_data, 'cmp_day');
+
+//Get the percent difference
+$diff_x = array();
+
+for ($i=1; $i < count($temp_data); $i++)
+{
+ $diff_x[] = $temp_data[$i]['x']/$temp_data[$i-1]['x']*100;
+}
+
+$split = 0;
+//Split (split represented by -1)
+if (count($diff_x) > 0)
+{
+ while (max($diff_x) > 120)
+ {
+ $diff_x[array_search(max($diff_x), $diff_x)] = -1;
+ $split++;
+ }
+}
+
+//Fill empty chart data for the template
+$chart_data = array();
+for ($i=0; $i < $nb_weeks; $i++)
+{
+ for ($j=1; $j <= 7; $j++)
+ {
+ $chart_data[$i][$j] = 0;
+ }
+}
+
+$size = 1;
+
+if (isset($temp_data[0]))
+{
+ $chart_data[$temp_data[0]['w']][$temp_data[0]['d']] = $size;
+}
+
+//Set sizes in chart data
+for ($i=1; $i < count($temp_data); $i++)
+{
+ if ($diff_x[$i-1] == -1)
+ {
+ $size++;
+ }
+ $chart_data[$temp_data[$i]['w']][$temp_data[$i]['d']] = $size;
+}
+
+//Assign data for the template
+$template->assign('ACTIVITY_WEEK_NUMBER',$week_number);
+$template->assign('ACTIVITY_LAST_WEEKS', $activity_last_weeks);
+$template->assign('ACTIVITY_CHART_DATA',$chart_data);
+$template->assign('ACTIVITY_CHART_NUMBER_SIZES',$size);
+
+$day_labels = array();
+for ($i=0; $i<=6; $i++)
+{
+ // first 3 letters of day name
+ $day_labels[] = mb_substr($lang['day'][($i+1)%7], 0, 3);
+}
+$template->assign('DAY_LABELS', $day_labels);
+
+// +-----------------------------------------------------------------------+
+// | get storage data |
+// +-----------------------------------------------------------------------+
+
+$video_format = array('webm','webmv','ogg','ogv','mp4','m4v', 'mov');
+$data_storage = array();
+
+//Select files in Image_Table
+$query = '
+SELECT
+ COUNT(*) AS ext_counter,
+ SUBSTRING_INDEX(path,".",-1) AS ext,
+ SUM(filesize) AS filesize
+ FROM `'.IMAGES_TABLE.'`
+ GROUP BY ext
+;';
+
+$file_extensions = query2array($query, 'ext');
+
+foreach ($file_extensions as $ext => $ext_details)
+{
+ $type = null;
+ if (in_array(strtolower($ext), $conf['picture_ext']))
+ {
+ $type = 'Photos';
+ }
+ elseif (in_array(strtolower($ext), $video_format))
+ {
+ $type = 'Videos';
+ }
+ else
+ {
+ $type = 'Other';
+ }
+
+ @$data_storage[$type]['total']['filesize'] += $ext_details['filesize'];
+ @$data_storage[$type]['total']['nb_files'] += $ext_details['ext_counter'];
+
+ @$data_storage[$type]['details'][strtoupper($ext)] = array(
+ 'filesize' => $ext_details['filesize'],
+ 'nb_files' => $ext_details['ext_counter'],
+ );
+}
+
+//Select files from format table
+$query = '
+SELECT
+ COUNT(*) AS ext_counter,
+ ext,
+ SUM(filesize) AS filesize
+ FROM `'.IMAGE_FORMAT_TABLE.'`
+ GROUP BY ext
+;';
+
+$file_extensions = query2array($query, 'ext');
+foreach ($file_extensions as $ext => $ext_details)
+{
+ $type = 'Formats';
+
+ @$data_storage[$type]['total']['filesize'] += $ext_details['filesize'];
+ @$data_storage[$type]['total']['nb_files'] += $ext_details['ext_counter'];
+
+ @$data_storage[$type]['details'][strtoupper($ext)] = array(
+ 'filesize' => $ext_details['filesize'],
+ 'nb_files' => $ext_details['ext_counter'],
+ );
+}
+
+// Add cache size if requested and known.
+if ($conf['add_cache_to_storage_chart'] && isset($conf['cache_sizes']))
+{
+ $cache_sizes = unserialize($conf['cache_sizes']);
+ if (isset($cache_sizes))
+ {
+ if (isset($cache_sizes[0]) && isset($cache_sizes[0]['value']))
+ {
+ @$data_storage['Cache']['total']['filesize'] = $cache_sizes[0]['value']/1024;
+ }
+ }
+}
+
+//Calculate total storage
+$total_storage = 0;
+foreach ($data_storage as $value)
+{
+ $total_storage += $value['total']['filesize'];
+}
+
+//Pass data to HTML
+$template->assign('STORAGE_TOTAL',$total_storage);
+$template->assign('STORAGE_CHART_DATA',$data_storage);
+
+// +-----------------------------------------------------------------------+
+// | sending html code |
+// +-----------------------------------------------------------------------+
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'intro');
+
+// Check integrity
+$c13y = new check_integrity();
+// add internal checks
+new c13y_internal();
+// check and display
+$c13y->check();
+$c13y->display();
+
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/languages.php b/Piwingo/piwigo-data/piwigo/admin/languages.php
new file mode 100644
index 0000000..d275f49
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/languages.php
@@ -0,0 +1,41 @@
+set_id('languages');
+$tabsheet->select($page['tab']);
+$tabsheet->assign();
+
+if ($page['tab'] == 'update') {
+ include(PHPWG_ROOT_PATH.'admin/updates_ext.php');
+ $template->assign('ADMIN_PAGE_TITLE', l10n('Languages'));
+}
+else
+{
+ include(PHPWG_ROOT_PATH.'admin/languages_'.$page['tab'].'.php');
+}
+?>
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/languages_installed.php b/Piwingo/piwigo-data/piwigo/admin/languages_installed.php
new file mode 100644
index 0000000..97e2a2f
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/languages_installed.php
@@ -0,0 +1,123 @@
+set_filenames(array('languages' => 'languages_installed.tpl'));
+
+$base_url = get_root_url().'admin.php?page='.$page['page'];
+
+$languages = new languages();
+$languages->get_db_languages();
+
+//--------------------------------------------------perform requested actions
+check_input_parameter('action', $_GET, false, '/^(activate|deactivate|set_default|delete)$/');
+check_input_parameter('language', $_GET, false, '/^('.join('|', array_keys($languages->fs_languages)).')$/');
+
+if (isset($_GET['action']) and isset($_GET['language']) and is_webmaster())
+{
+ $page['errors'] = $languages->perform_action($_GET['action'], $_GET['language']);
+
+ if (empty($page['errors']))
+ {
+ redirect($base_url);
+ }
+}
+
+// +-----------------------------------------------------------------------+
+// | start template output |
+// +-----------------------------------------------------------------------+
+$default_language = get_default_language();
+
+$tpl_languages = array();
+
+foreach($languages->fs_languages as $language_id => $language)
+{
+ $language['u_action'] = add_url_params($base_url, array('language' => $language_id));
+
+ if (in_array($language_id, array_keys($languages->db_languages)))
+ {
+ $language['state'] = 'active';
+ $language['deactivable'] = true;
+
+ if (count($languages->db_languages) <= 1)
+ {
+ $language['deactivable'] = false;
+ $language['deactivate_tooltip'] = l10n('Impossible to deactivate this language, you need at least one language.');
+ }
+
+ if ($language_id == $default_language)
+ {
+ $language['deactivable'] = false;
+ $language['deactivate_tooltip'] = l10n('Impossible to deactivate this language, first set another language as default.');
+ }
+ }
+ else
+ {
+ $language['state'] = 'inactive';
+ }
+
+ if ($language_id == $default_language)
+ {
+ $language['is_default'] = true;
+ array_unshift($tpl_languages, $language);
+ }
+ else
+ {
+ $language['is_default'] = false;
+ $tpl_languages[] = $language;
+ }
+}
+
+$template->assign(
+ array(
+ 'languages' => $tpl_languages,
+ )
+ );
+$template->append('language_states', 'active');
+$template->append('language_states', 'inactive');
+
+
+$missing_language_ids = array_diff(
+ array_keys($languages->db_languages),
+ array_keys($languages->fs_languages)
+ );
+
+foreach($missing_language_ids as $language_id)
+{
+ $query = '
+UPDATE '.USER_INFOS_TABLE.'
+ SET language = \''.get_default_language().'\'
+ WHERE language = \''.$language_id.'\'
+;';
+ pwg_query($query);
+
+ $query = '
+DELETE
+ FROM '.LANGUAGES_TABLE.'
+ WHERE id= \''.$language_id.'\'
+;';
+ pwg_query($query);
+}
+
+$template->assign('isWebmaster', (is_webmaster()) ? 1 : 0);
+$template->assign('ADMIN_PAGE_TITLE', l10n('Languages'));
+$template->assign('CONF_ENABLE_EXTENSIONS_INSTALL', $conf['enable_extensions_install']);
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'languages');
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/languages_new.php b/Piwingo/piwigo-data/piwigo/admin/languages_new.php
new file mode 100644
index 0000000..d0d408f
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/languages_new.php
@@ -0,0 +1,120 @@
+set_filenames(array('languages' => 'languages_new.tpl'));
+
+$base_url = get_root_url().'admin.php?page='.$page['page'].'&tab='.$page['tab'];
+
+$languages = new languages();
+$languages->get_db_languages();
+
+// +-----------------------------------------------------------------------+
+// | setup check |
+// +-----------------------------------------------------------------------+
+
+$languages_dir = PHPWG_ROOT_PATH.'language';
+if (!is_writable($languages_dir))
+{
+ $page['errors'][] = l10n('Add write access to the "%s" directory', 'language');
+}
+
+// +-----------------------------------------------------------------------+
+// | perform installation |
+// +-----------------------------------------------------------------------+
+
+if (isset($_GET['revision']))
+{
+ if (!is_webmaster())
+ {
+ $page['errors'][] = l10n('Webmaster status is required.');
+ }
+ else
+ {
+ check_pwg_token();
+
+ $install_status = $languages->extract_language_files('install', $_GET['revision']);
+
+ redirect($base_url.'&installstatus='.$install_status);
+ }
+}
+
+// +-----------------------------------------------------------------------+
+// | installation result |
+// +-----------------------------------------------------------------------+
+if (isset($_GET['installstatus']))
+{
+ switch ($_GET['installstatus'])
+ {
+ case 'ok':
+ $page['infos'][] = l10n('Language has been successfully installed');
+ break;
+
+ case 'temp_path_error':
+ $page['errors'][] = l10n('Can\'t create temporary file.');
+ break;
+
+ case 'dl_archive_error':
+ $page['errors'][] = l10n('Can\'t download archive.');
+ break;
+
+ case 'archive_error':
+ $page['errors'][] = l10n('Can\'t read or extract archive.');
+ break;
+
+ default:
+ $page['errors'][] = l10n('An error occured during extraction (%s).', htmlspecialchars($_GET['installstatus']));
+ }
+}
+
+// +-----------------------------------------------------------------------+
+// | start template output |
+// +-----------------------------------------------------------------------+
+if ($languages->get_server_languages(true))
+{
+ foreach($languages->server_languages as $language)
+ {
+ list($date, ) = explode(' ', $language['revision_date']);
+
+ $url_auto_install = htmlentities($base_url)
+ . '&revision=' . $language['revision_id']
+ . '&pwg_token='.get_pwg_token()
+ ;
+
+ $template->append('languages', array(
+ 'EXT_NAME' => $language['extension_name'],
+ 'EXT_DESC' => $language['extension_description'],
+ 'EXT_URL' => PEM_URL.'/extension_view.php?eid='.$language['extension_id'],
+ 'VERSION' => $language['revision_name'],
+ 'VER_DESC' => $language['revision_description'],
+ 'DATE' => $date,
+ 'AUTHOR' => $language['author_name'],
+ 'URL_INSTALL' => $url_auto_install,
+ 'URL_DOWNLOAD' => $language['download_url'] . '&origin=piwigo_download'));
+ }
+}
+else
+{
+ $page['errors'][] = l10n('Can\'t connect to server.');
+}
+$template->assign('ADMIN_PAGE_TITLE', l10n('Languages'));
+$template->assign('isWebmaster', (is_webmaster()) ? 1 : 0);
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'languages');
+?>
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/maintenance.php b/Piwingo/piwigo-data/piwigo/admin/maintenance.php
new file mode 100644
index 0000000..34c8201
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/maintenance.php
@@ -0,0 +1,125 @@
+ array(
+ 'icon' => 'icon-trash-1',
+ 'label' => l10n('Delete multiple size images'),
+ ),
+ 'lock_gallery' => array(
+ 'icon' => 'icon-lock',
+ 'label' => l10n('Lock gallery'),
+ ),
+ 'unlock_gallery' => array(
+ 'icon' => 'icon-lock',
+ 'label' => l10n('Unlock gallery'),
+ ),
+ 'categories' => array(
+ 'icon' => 'icon-folder-open',
+ 'label' => l10n('Update albums informations'),
+ ),
+ 'images' => array(
+ 'icon' => 'icon-info-circled-1',
+ 'label' => l10n('Update photos information'),
+ ),
+ 'empty_lounge' => array(
+ 'icon' => 'icon-thumbs-up',
+ 'label' => l10n('Empty lounge'),
+ ),
+ 'delete_orphan_tags' => array(
+ 'icon' => 'icon-tags',
+ 'label' => l10n('Delete orphan tags'),
+ ),
+ 'user_cache' => array(
+ 'icon' => 'icon-user-1',
+ 'label' => l10n('Purge user cache'),
+ ),
+ 'history_detail' => array(
+ 'icon' => 'icon-back-in-time',
+ 'label' => l10n('Purge history detail'),
+ ),
+ 'history_summary' => array(
+ 'icon' => 'icon-back-in-time',
+ 'label' => l10n('Purge history summary'),
+ ),
+ 'sessions' => array(
+ 'icon' => 'icon-th-list',
+ 'label' => l10n('Purge sessions'),
+ ),
+ 'feeds' => array(
+ 'icon' => 'icon-bell',
+ 'label' => l10n('Purge never used notification feeds'),
+ ),
+ 'database' => array(
+ 'icon' => 'icon-database',
+ 'label' => l10n('Repair and optimize database'),
+ ),
+ 'c13y' => array(
+ 'icon' => 'icon-ok',
+ 'label' => l10n('Reinitialize check integrity'),
+ ),
+ 'search' => array(
+ 'icon' => 'icon-search',
+ 'label' => l10n('Purge search history'),
+ ),
+ 'compiled-templates' => array(
+ 'icon' => 'icon-file-code',
+ 'label' => l10n('Purge compiled templates'),
+ ),
+);
+
+// +-----------------------------------------------------------------------+
+// | tabs |
+// +-----------------------------------------------------------------------+
+
+include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
+$my_base_url = get_root_url().'admin.php?page=';
+
+if (isset($_GET['tab']))
+{
+ check_input_parameter('tab', $_GET, false, '/^(actions|env|sys)$/');
+ $page['tab'] = $_GET['tab'];
+}
+else
+{
+ $page['tab'] = 'actions';
+}
+
+
+$tabsheet = new tabsheet();
+$tabsheet->set_id('maintenance');
+$tabsheet->select($page['tab']);
+$tabsheet->assign();
+
+include(PHPWG_ROOT_PATH.'admin/maintenance_'.$page['tab'].'.php');
+
+$template->assign(
+ array('ADMIN_PAGE_TITLE' => l10n('Maintenance'))
+);
diff --git a/Piwingo/piwigo-data/piwigo/admin/maintenance_actions.php b/Piwingo/piwigo-data/piwigo/admin/maintenance_actions.php
new file mode 100644
index 0000000..ea07c55
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/maintenance_actions.php
@@ -0,0 +1,409 @@
+$action));
+ redirect(get_root_url().'admin.php?page=maintenance');
+ break;
+ }
+ case 'unlock_gallery' :
+ {
+ conf_update_param('gallery_locked', 'false');
+ $_SESSION['page_infos'] = array(l10n('Gallery unlocked'));
+ pwg_activity('system', ACTIVITY_SYSTEM_CORE, 'maintenance', array('maintenance_action'=>$action));
+ redirect(get_root_url().'admin.php?page=maintenance');
+ break;
+ }
+ case 'categories' :
+ {
+ images_integrity();
+ categories_integrity();
+ update_uppercats();
+ update_category('all');
+ update_global_rank();
+ invalidate_user_cache(true);
+ $page['infos'][] = sprintf('%s : %s', l10n('Update albums informations'), l10n('action successfully performed.'));
+ break;
+ }
+ case 'images' :
+ {
+ images_integrity();
+ update_path();
+ include_once(PHPWG_ROOT_PATH.'include/functions_rate.inc.php');
+ update_rating_score();
+ invalidate_user_cache();
+ $page['infos'][] = sprintf('%s : %s', l10n('Update photos information'), l10n('action successfully performed.'));
+ break;
+ }
+ case 'delete_orphan_tags' :
+ {
+ delete_orphan_tags();
+ $page['infos'][] = sprintf('%s : %s', l10n('Delete orphan tags'), l10n('action successfully performed.'));
+ break;
+ }
+ case 'user_cache' :
+ {
+ invalidate_user_cache();
+ $page['infos'][] = sprintf('%s : %s', l10n('Purge user cache'), l10n('action successfully performed.'));
+ break;
+ }
+ case 'history_detail' :
+ {
+ $query = '
+DELETE
+ FROM '.HISTORY_TABLE.'
+;';
+ pwg_query($query);
+ $page['infos'][] = sprintf('%s : %s', l10n('Purge history detail'), l10n('action successfully performed.'));
+ break;
+ }
+ case 'history_summary' :
+ {
+ $query = '
+DELETE
+ FROM '.HISTORY_SUMMARY_TABLE.'
+;';
+ pwg_query($query);
+ $page['infos'][] = sprintf('%s : %s', l10n('Purge history summary'), l10n('action successfully performed.'));
+ break;
+ }
+ case 'sessions' :
+ {
+ pwg_session_gc();
+
+ // delete all sessions associated to invalid user ids (it should never happen)
+ $query = '
+SELECT
+ id,
+ data
+ FROM '.SESSIONS_TABLE.'
+;';
+ $sessions = query2array($query);
+
+ $query = '
+SELECT
+ '.$conf['user_fields']['id'].' AS id
+ FROM '.USERS_TABLE.'
+;';
+ $all_user_ids = query2array($query, 'id', null);
+
+ $sessions_to_delete = array();
+
+ foreach ($sessions as $session)
+ {
+ if (preg_match('/pwg_uid\|i:(\d+);/', $session['data'], $matches))
+ {
+ if (!isset($all_user_ids[ $matches[1] ]))
+ {
+ $sessions_to_delete[] = $session['id'];
+ }
+ }
+ }
+
+ if (count($sessions_to_delete) > 0)
+ {
+ $query = '
+DELETE
+ FROM '.SESSIONS_TABLE.'
+ WHERE id IN (\''.implode("','", $sessions_to_delete).'\')
+;';
+ pwg_query($query);
+ }
+ $page['infos'][] = sprintf('%s : %s', l10n('Purge sessions'), l10n('action successfully performed.'));
+ break;
+ }
+ case 'feeds' :
+ {
+ $query = '
+DELETE
+ FROM '.USER_FEED_TABLE.'
+ WHERE last_check IS NULL
+;';
+ pwg_query($query);
+ $page['infos'][] = sprintf('%s : %s', l10n('Purge never used notification feeds'), l10n('action successfully performed.'));
+ break;
+ }
+ case 'database' :
+ {
+ do_maintenance_all_tables();
+ break;
+ }
+ case 'c13y' :
+ {
+ include_once(PHPWG_ROOT_PATH.'admin/include/check_integrity.class.php');
+ $c13y = new check_integrity();
+ $c13y->maintenance();
+ $page['infos'][] = sprintf('%s : %s', l10n('Reinitialize check integrity'), l10n('action successfully performed.'));
+ break;
+ }
+ case 'empty_lounge':
+ {
+ $rows = empty_lounge();
+ $page['infos'][] = sprintf('%d photos were moved from the upload lounge to their albums', count($rows));
+ break;
+ }
+ case 'search' :
+ {
+ $query = '
+DELETE
+ FROM '.SEARCH_TABLE.'
+;';
+ pwg_query($query);
+ sprintf('%s : %s', l10n('Reinitialize check integrity'), l10n('action successfully performed.'));
+ break;
+ }
+ case 'compiled-templates':
+ {
+ $template->delete_compiled_templates();
+ FileCombiner::clear_combined_files();
+ $persistent_cache->purge(true);
+ $page['infos'][] = sprintf('%s : %s', l10n('Purge compiled templates'), l10n('action successfully performed.'));
+ break;
+ }
+ case 'derivatives':
+ {
+ $types_str = $_GET['type'];
+ if ($types_str == "all") {
+ clear_derivative_cache($_GET['type']);
+ } else {
+ $types = explode('_', $types_str);
+ foreach ($types as $type_to_clear) {
+ clear_derivative_cache($type_to_clear);
+ }
+ }
+ $page['infos'][] = l10n('action successfully performed.');
+ break;
+ }
+
+ case 'check_upgrade':
+ {
+ if (!fetchRemote(PHPWG_URL.'/download/latest_version', $result))
+ {
+ $page['errors'][] = l10n('Unable to check for upgrade.');
+ }
+ else
+ {
+ $versions = array('current' => PHPWG_VERSION);
+ $lines = @explode("\r\n", $result);
+
+ // if the current version is a BSF (development branch) build, we check
+ // the first line, for stable versions, we check the second line
+ if (preg_match('/^BSF/', $versions['current']))
+ {
+ $versions['latest'] = trim($lines[0]);
+
+ // because integer are limited to 4,294,967,296 we need to split BSF
+ // versions in date.time
+ foreach ($versions as $key => $value)
+ {
+ $versions[$key] =
+ preg_replace('/BSF_(\d{8})(\d{4})/', '$1.$2', $value);
+ }
+ }
+ else
+ {
+ $versions['latest'] = trim($lines[1]);
+ }
+
+ if ('' == $versions['latest'])
+ {
+ $page['errors'][] = l10n('Check for upgrade failed for unknown reasons.');
+ }
+ // concatenation needed to avoid automatic transformation by release
+ // script generator
+ else if ('%'.'PWGVERSION'.'%' == $versions['current'])
+ {
+ $page['infos'][] = l10n('You are running on development sources, no check possible.');
+ }
+ else if (version_compare($versions['current'], $versions['latest']) < 0)
+ {
+ $page['infos'][] = l10n('A new version of Piwigo is available.');
+ }
+ else
+ {
+ $page['infos'][] = l10n('You are running the latest version of Piwigo.');
+ }
+ }
+ $page['infos'][] = l10n('action successfully performed.');
+ }
+
+ default :
+ {
+ $register_activity = false;
+ break;
+ }
+}
+
+if ($register_activity)
+{
+ pwg_activity('system', ACTIVITY_SYSTEM_CORE, 'maintenance', array('maintenance_action'=>$action));
+}
+
+// +-----------------------------------------------------------------------+
+// | template init |
+// +-----------------------------------------------------------------------+
+
+$template->set_filenames(array('maintenance'=>'maintenance_actions.tpl'));
+$pwg_token = get_pwg_token();
+$url_format = get_root_url().'admin.php?page=maintenance&action=%s&pwg_token='.get_pwg_token();
+
+if (!is_webmaster())
+{
+ $page['warnings'][] = str_replace('%s', l10n('user_status_webmaster'), l10n('%s status is required to edit parameters.'));
+}
+
+$purge_urls[l10n('All')] = 'all';
+foreach(ImageStdParams::get_defined_type_map() as $params)
+{
+ $purge_urls[ l10n($params->type) ] = $params->type;
+}
+$purge_urls[ l10n(IMG_CUSTOM) ] = IMG_CUSTOM;
+
+$php_current_timestamp = date("Y-m-d H:i:s");
+$db_version = pwg_get_db_version();
+list($db_current_date) = pwg_db_fetch_row(pwg_query('SELECT now();'));
+
+$template->assign(
+ array(
+ 'maint_actions' => $maint_actions,
+ 'U_MAINT_CATEGORIES' => sprintf($url_format, 'categories'),
+ 'U_MAINT_IMAGES' => sprintf($url_format, 'images'),
+ 'U_MAINT_ORPHAN_TAGS' => sprintf($url_format, 'delete_orphan_tags'),
+ 'U_MAINT_USER_CACHE' => sprintf($url_format, 'user_cache'),
+ 'U_MAINT_HISTORY_DETAIL' => sprintf($url_format, 'history_detail'),
+ 'U_MAINT_HISTORY_SUMMARY' => sprintf($url_format, 'history_summary'),
+ 'U_MAINT_SESSIONS' => sprintf($url_format, 'sessions'),
+ 'U_MAINT_FEEDS' => sprintf($url_format, 'feeds'),
+ 'U_MAINT_DATABASE' => sprintf($url_format, 'database'),
+ 'U_MAINT_C13Y' => sprintf($url_format, 'c13y'),
+ 'U_MAINT_SEARCH' => sprintf($url_format, 'search'),
+ 'U_MAINT_COMPILED_TEMPLATES' => sprintf($url_format, 'compiled-templates'),
+ 'U_MAINT_DERIVATIVES' => sprintf($url_format, 'derivatives'),
+ 'purge_derivatives' => $purge_urls,
+ 'U_HELP' => get_root_url().'admin/popuphelp.php?page=maintenance',
+
+ 'PHPWG_URL' => PHPWG_URL,
+ 'PWG_VERSION' => PHPWG_VERSION,
+ 'U_CHECK_UPGRADE' => sprintf($url_format, 'check_upgrade'),
+ 'OS' => PHP_OS,
+ 'PHP_VERSION' => phpversion(),
+ 'DB_ENGINE' => 'MySQL',
+ 'DB_VERSION' => $db_version,
+ 'U_PHPINFO' => sprintf($url_format, 'phpinfo'),
+ 'PHP_DATATIME' => $php_current_timestamp,
+ 'DB_DATATIME' => $db_current_date,
+ 'pwg_token' => $pwg_token,
+ 'cache_sizes' => (isset($conf['cache_sizes'])) ? unserialize($conf['cache_sizes']) : null,
+ 'time_elapsed_since_last_calc' => (isset($conf['cache_sizes'])) ? time_since(unserialize($conf['cache_sizes'])[3]['value'], 'year') : null,
+ )
+ );
+
+// graphics library
+switch (pwg_image::get_library())
+{
+ case 'ext_imagick':
+ $library = 'External ImageMagick';
+ exec($conf['ext_imagick_dir'].pwg_image::get_ext_imagick_command().' -version', $returnarray);
+ if (preg_match('/Version: ImageMagick (\d+\.\d+\.\d+-?\d*)/', $returnarray[0], $match))
+ {
+ $library .= ' ' . $match[1];
+ }
+ $template->assign('GRAPHICS_LIBRARY', $library);
+ break;
+
+ case 'imagick':
+ $library = 'ImageMagick';
+ $img = new Imagick();
+ $version = $img->getVersion();
+ if (preg_match('/ImageMagick \d+\.\d+\.\d+-?\d*/', $version['versionString'], $match))
+ {
+ $library = $match[0];
+ }
+ $template->assign('GRAPHICS_LIBRARY', $library);
+ break;
+
+ case 'gd':
+ $gd_info = gd_info();
+ $template->assign('GRAPHICS_LIBRARY', 'GD '.@$gd_info['GD Version']);
+ break;
+}
+
+if ($conf['gallery_locked'])
+{
+ $template->assign(
+ array(
+ 'U_MAINT_UNLOCK_GALLERY' => sprintf($url_format, 'unlock_gallery'),
+ )
+ );
+}
+else
+{
+ $template->assign(
+ array(
+ 'U_MAINT_LOCK_GALLERY' => sprintf($url_format, 'lock_gallery'),
+ )
+ );
+}
+
+$query = '
+SELECT
+ COUNT(*)
+ FROM '.LOUNGE_TABLE.'
+;';
+list($nb_lounge) = pwg_db_fetch_row(pwg_query($query));
+
+if ($nb_lounge > 0)
+{
+ $template->assign(
+ array(
+ 'U_EMPTY_LOUNGE' => sprintf($url_format, 'empty_lounge'),
+ 'LOUNGE_COUNTER' => $nb_lounge,
+ )
+ );
+}
+
+$template->assign('isWebmaster', (is_webmaster()) ? 1 : 0);
+
+// +-----------------------------------------------------------------------+
+// | Define advanced features |
+// +-----------------------------------------------------------------------+
+
+$advanced_features = array();
+
+//$advanced_features is array of array composed of CAPTION & URL
+$advanced_features = trigger_change(
+ 'get_admin_advanced_features_links',
+ $advanced_features
+ );
+
+$template->assign('advanced_features', $advanced_features);
+
+// +-----------------------------------------------------------------------+
+// | sending html code |
+// +-----------------------------------------------------------------------+
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'maintenance');
+?>
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/maintenance_env.php b/Piwingo/piwigo-data/piwigo/admin/maintenance_env.php
new file mode 100644
index 0000000..b53a73d
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/maintenance_env.php
@@ -0,0 +1,365 @@
+ 0)
+ {
+ $query = '
+DELETE
+ FROM '.SESSIONS_TABLE.'
+ WHERE id IN (\''.implode("','", $sessions_to_delete).'\')
+;';
+ pwg_query($query);
+ }
+
+ break;
+ }
+ case 'feeds' :
+ {
+ $query = '
+DELETE
+ FROM '.USER_FEED_TABLE.'
+ WHERE last_check IS NULL
+;';
+ pwg_query($query);
+ break;
+ }
+ case 'database' :
+ {
+ do_maintenance_all_tables();
+ break;
+ }
+ case 'c13y' :
+ {
+ include_once(PHPWG_ROOT_PATH.'admin/include/check_integrity.class.php');
+ $c13y = new check_integrity();
+ $c13y->maintenance();
+ break;
+ }
+ case 'search' :
+ {
+ $query = '
+DELETE
+ FROM '.SEARCH_TABLE.'
+;';
+ pwg_query($query);
+ break;
+ }
+ case 'compiled-templates':
+ {
+ $template->delete_compiled_templates();
+ FileCombiner::clear_combined_files();
+ $persistent_cache->purge(true);
+ break;
+ }
+ case 'derivatives':
+ {
+ clear_derivative_cache($_GET['type']);
+ break;
+ }
+
+ case 'check_upgrade':
+ {
+ if (!fetchRemote(PHPWG_URL.'/download/latest_version', $result))
+ {
+ $page['errors'][] = l10n('Unable to check for upgrade.');
+ }
+ else
+ {
+ $versions = array('current' => PHPWG_VERSION);
+ $lines = @explode("\r\n", $result);
+
+ // if the current version is a BSF (development branch) build, we check
+ // the first line, for stable versions, we check the second line
+ if (preg_match('/^BSF/', $versions['current']))
+ {
+ $versions['latest'] = trim($lines[0]);
+
+ // because integer are limited to 4,294,967,296 we need to split BSF
+ // versions in date.time
+ foreach ($versions as $key => $value)
+ {
+ $versions[$key] =
+ preg_replace('/BSF_(\d{8})(\d{4})/', '$1.$2', $value);
+ }
+ }
+ else
+ {
+ $versions['latest'] = trim($lines[1]);
+ }
+
+ if ('' == $versions['latest'])
+ {
+ $page['errors'][] = l10n('Check for upgrade failed for unknown reasons.');
+ }
+ // concatenation needed to avoid automatic transformation by release
+ // script generator
+ else if ('%'.'PWGVERSION'.'%' == $versions['current'])
+ {
+ $page['infos'][] = l10n('You are running on development sources, no check possible.');
+ }
+ else if (version_compare($versions['current'], $versions['latest']) < 0)
+ {
+ $page['infos'][] = l10n('A new version of Piwigo is available.');
+
+ $update_url = PHPWG_ROOT_PATH.'admin.php?page=updates';
+ $page['infos'][] = '' . l10n('Update to Piwigo %s', $versions['latest']) . '';
+ }
+ else
+ {
+ $page['infos'][] = l10n('You are running the latest version of Piwigo.');
+ }
+ }
+ }
+
+ default :
+ {
+ break;
+ }
+}
+
+
+// +-----------------------------------------------------------------------+
+// | template init |
+// +-----------------------------------------------------------------------+
+
+$template->set_filenames(array('maintenance'=>'maintenance_env.tpl'));
+
+$url_format = get_root_url().'admin.php?page=maintenance&action=%s&pwg_token='.get_pwg_token();
+
+$purge_urls[l10n('All')] = sprintf($url_format, 'derivatives').'&type=all';
+foreach(ImageStdParams::get_defined_type_map() as $params)
+{
+ $purge_urls[ l10n($params->type) ] = sprintf($url_format, 'derivatives').'&type='.$params->type;
+}
+$purge_urls[ l10n(IMG_CUSTOM) ] = sprintf($url_format, 'derivatives').'&type='.IMG_CUSTOM;
+
+$php_current_timestamp = date("Y-m-d H:i:s");
+$db_version = pwg_get_db_version();
+list($db_current_date) = pwg_db_fetch_row(pwg_query('SELECT now();'));
+
+list($container_name,$container_version) = get_container_info();
+
+if (!in_array($container_name, ['Official','none']))
+{
+ $container_name = '(unofficial) '.$container_name;
+}
+
+$template->assign(
+ array(
+ 'U_MAINT_CATEGORIES' => sprintf($url_format, 'categories'),
+ 'U_MAINT_IMAGES' => sprintf($url_format, 'images'),
+ 'U_MAINT_ORPHAN_TAGS' => sprintf($url_format, 'delete_orphan_tags'),
+ 'U_MAINT_USER_CACHE' => sprintf($url_format, 'user_cache'),
+ 'U_MAINT_HISTORY_DETAIL' => sprintf($url_format, 'history_detail'),
+ 'U_MAINT_HISTORY_SUMMARY' => sprintf($url_format, 'history_summary'),
+ 'U_MAINT_SESSIONS' => sprintf($url_format, 'sessions'),
+ 'U_MAINT_FEEDS' => sprintf($url_format, 'feeds'),
+ 'U_MAINT_DATABASE' => sprintf($url_format, 'database'),
+ 'U_MAINT_C13Y' => sprintf($url_format, 'c13y'),
+ 'U_MAINT_SEARCH' => sprintf($url_format, 'search'),
+ 'U_MAINT_COMPILED_TEMPLATES' => sprintf($url_format, 'compiled-templates'),
+ 'U_MAINT_DERIVATIVES' => sprintf($url_format, 'derivatives'),
+ 'purge_derivatives' => $purge_urls,
+ 'U_HELP' => get_root_url().'admin/popuphelp.php?page=maintenance',
+
+ 'PHPWG_URL' => PHPWG_URL,
+ 'PWG_VERSION' => PHPWG_VERSION,
+ 'U_CHECK_UPGRADE' => sprintf($url_format, 'check_upgrade'),
+ 'OS' => PHP_OS,
+ 'CONTAINER_INFO' => $container_name.(!empty($container_version) ? ' '.$container_version : ''),
+ 'PHP_VERSION' => phpversion(),
+ 'DB_ENGINE' => 'MySQL',
+ 'DB_VERSION' => $db_version,
+ 'U_PHPINFO' => sprintf($url_format, 'phpinfo'),
+ 'PHP_DATATIME' => $php_current_timestamp,
+ 'DB_DATATIME' => $db_current_date,
+ 'cache_sizes' => (isset($conf['cache_sizes'])) ? unserialize($conf['cache_sizes']) : null,
+ 'time_elapsed_since_last_calc' => (isset($conf['cache_sizes'])) ? time_since(unserialize($conf['cache_sizes'])[3]['value'], 'year') : null,
+ )
+ );
+
+// graphics library
+$graphics_library = get_graphics_library_label();
+if (!empty($graphics_library))
+{
+ $template->assign('GRAPHICS_LIBRARY', $graphics_library);
+}
+
+if ($conf['gallery_locked'])
+{
+ $template->assign(
+ array(
+ 'U_MAINT_UNLOCK_GALLERY' => sprintf($url_format, 'unlock_gallery'),
+ )
+ );
+}
+else
+{
+ $template->assign(
+ array(
+ 'U_MAINT_LOCK_GALLERY' => sprintf($url_format, 'lock_gallery'),
+ )
+ );
+}
+
+$installed_on = get_installation_date();
+if (!empty($installed_on))
+{
+ $template->assign(
+ array(
+ 'INSTALLED_ON' => format_date($installed_on, array('day', 'month', 'year')),
+ 'INSTALLED_SINCE' => time_since($installed_on, 'day'),
+ )
+ );
+}
+
+// +-----------------------------------------------------------------------+
+// | Define advanced features |
+// +-----------------------------------------------------------------------+
+
+$advanced_features = array();
+
+//$advanced_features is array of array composed of CAPTION & URL
+$advanced_features = trigger_change(
+ 'get_admin_advanced_features_links',
+ $advanced_features
+ );
+
+$template->assign('advanced_features', $advanced_features);
+
+// +-----------------------------------------------------------------------+
+// | sending html code |
+// +-----------------------------------------------------------------------+
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'maintenance');
+?>
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/maintenance_sys.php b/Piwingo/piwigo-data/piwigo/admin/maintenance_sys.php
new file mode 100644
index 0000000..5fcd070
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/maintenance_sys.php
@@ -0,0 +1,382 @@
+ 'empty',
+ );
+
+ // For each categories (Core, Plugin and Theme) we need to format theirs actions
+ switch ($rows['object_id'])
+ {
+ case ACTIVITY_SYSTEM_CORE:
+ $object_icon = 'icon-piwigo';
+ $object = l10n('Core');
+
+ switch ($rows['action'])
+ {
+ case 'install':
+ $action_icon = 'icon-download';
+ $action_color = 'icon-green';
+ $action = l10n('Install');
+ break;
+
+ case 'config':
+ $action_icon = 'icon-cog-alt';
+ $action_color = 'icon-yellow';
+ $action = l10n('Configuration');
+ // for config we need to specific format details
+ if (isset($details['config_section']))
+ {
+ $c_icon = '';
+ $c_text = '';
+ switch ($details['config_section'])
+ {
+ case 'main':
+ $c_icon = 'icon-cog';
+ $c_text = l10n('General');
+ break;
+
+ case 'watermark':
+ $c_icon = 'icon-file-image';
+ $c_text = l10n('Watermark');
+ break;
+
+ case 'sizes':
+ $c_icon = 'icon-zoom-square';
+ $c_text = l10n('Photo sizes');
+ // sizes have 2 params always Photo sizes and sometimes config_action
+ if (isset($details['config_action']) && 'restore_settings' == $details['config_action'])
+ {
+ $detail[] = array(
+ 'icon' => 'icon-back-in-time',
+ 'text' => l10n('Set as default')
+ );
+ }
+ break;
+
+ case 'comments':
+ $c_icon = 'icon-chat';
+ $c_text = l10n('Comments');
+ break;
+
+ case 'display':
+ $c_icon = 'icon-television';
+ $c_text = l10n('Display');
+ break;
+
+ default:
+ $c_icon = 'icon-cog-alt';
+ $c_text = $details['config_section'];
+ break;
+ }
+
+ $detail['type'] = 'config_section';
+ $detail[] = array(
+ 'icon' => $c_icon,
+ 'text' => $c_text
+ );
+ }
+ break;
+
+ case 'maintenance':
+ $action_icon = 'icon-cone';
+ $action_color = 'icon-yellow';
+ $action = l10n('Maintenance');
+ // for maintenance we need to specific format details
+ if (isset($details['maintenance_action']))
+ {
+ $action_detail = $details['maintenance_action'];
+ $detail = array(
+ 'type' => 'maintenance_action',
+ 'icon' => $maint_actions[$action_detail]['icon'] ?? 'icon-cone',
+ 'text' => $maint_actions[$action_detail]['label'] ?? $action_detail,
+ );
+ }
+ break;
+
+ case 'update':
+ $action_icon = 'icon-arrows-cw';
+ $action_color = 'icon-blue';
+ $action = l10n('Update');
+ $major_infos = true;
+ break;
+
+ case 'autoupdate':
+ $action_icon = 'icon-arrows-cw';
+ $action_color = 'icon-blue';
+ $action = l10n('Auto-update');
+ $major_infos = true;
+ break;
+
+ default:
+ $action_icon = 'icon-download';
+ $action_color = 'icon-yellow';
+ break;
+ }
+ break;
+
+ case ACTIVITY_SYSTEM_PLUGIN:
+ $object_icon = 'icon-puzzle';
+ $object = 'plugin';
+ if (isset($details['plugin_id']))
+ {
+ $object = str_replace(['_', '-'], ' ', $details['plugin_id']);
+ }
+ switch ($rows['action'])
+ {
+ case 'install':
+ $action_icon = 'icon-download';
+ $action_color = 'icon-green';
+ $action = l10n('Install');
+ break;
+
+ case 'update':
+ $action_icon = 'icon-arrows-cw';
+ $action_color = 'icon-blue';
+ $action = l10n('Update');
+ break;
+
+ case 'activate':
+ $action_icon = 'icon-check';
+ $action_color = 'icon-green';
+ $action = l10n('Activate');
+ break;
+
+ case 'deactivate':
+ $action_icon = 'icon-block';
+ $action_color = 'icon-purple';
+ $action = l10n('Deactivate');
+ break;
+
+ case 'uninstall':
+ $action_icon = 'icon-trash-1';
+ $action_color = 'icon-red';
+ $action = l10n('Uninstall');
+ break;
+
+ case 'restore':
+ $action_icon = 'icon-back-in-time';
+ $action_color = 'icon-blue';
+ $action = l10n('Restore');
+ break;
+
+ case 'delete':
+ $action_icon = 'icon-trash-1';
+ $action_color = 'icon-red';
+ $action = l10n('Delete');
+ // for delete we need to specific format details
+ if (isset($details['db_version']))
+ {
+ $detail['type'] = 'db_fs_version';
+ $detail[] = array(
+ 'icon' => 'icon-flow-branch',
+ 'text' => 'database : ' . $details['db_version']
+ );
+ }
+ if (isset($details['fs_version']))
+ {
+ $detail['type'] = 'db_fs_version';
+ $detail[] = array(
+ 'icon' => 'icon-flow-branch',
+ 'text' => 'filesystem : ' . $details['fs_version']
+ );
+ }
+ break;
+
+ case 'autoupdate':
+ $action_icon = 'icon-arrows-cw';
+ $action_color = 'icon-blue';
+ $action = l10n('Auto-update');
+ break;
+
+ default:
+ $action_icon = 'icon-puzzle';
+ $action_color = 'icon-yellow';
+ break;
+ }
+ break;
+
+ case ACTIVITY_SYSTEM_THEME:
+ $object_icon = 'icon-brush';
+ $object = 'theme';
+ if (isset($details['theme_id']))
+ {
+ $object = str_replace(['_', '-'], ' ', $details['theme_id']);
+ }
+
+ switch ($rows['action'])
+ {
+ case 'install':
+ $action_icon = 'icon-download';
+ $action_color = 'icon-green';
+ $action = l10n('Install');
+ break;
+
+ case 'activate':
+ $action_icon = 'icon-check';
+ $action_color = 'icon-green';
+ $action = l10n('Activate');
+ break;
+
+ case 'deactivate':
+ $action_icon = 'icon-block';
+ $action_color = 'icon-purple';
+ $action = l10n('Deactivate');
+ break;
+
+ case 'delete':
+ $action_icon = 'icon-trash-1';
+ $action_color = 'icon-red';
+ $action = l10n('Delete');
+ break;
+
+ case 'set_default':
+ $action_icon = 'icon-star';
+ $action_color = 'icon-yellow';
+ $action = l10n('Set as default');
+ break;
+
+ case 'update':
+ $action_icon = 'icon-arrows-cw';
+ $action_color = 'icon-blue';
+ $action = l10n('Update');
+ break;
+
+ default:
+ $action_icon = 'icon-brush';
+ $action_color = 'icon-yellow';
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ // For each lines we need to format theirs details (general details)
+ if (isset($details['from_version']))
+ {
+ $detail = array(
+ 'type' => 'from_to',
+ array(
+ 'icon' => 'icon-flow-branch',
+ 'text' => $details['from_version'],
+ ),
+ array(
+ 'icon' => isset($details['to_version']) ? 'icon-flow-branch' : 'icon-block',
+ 'text' => isset($details['to_version']) ? $details['to_version'] : ($details['result'] ?? ''),
+ ),
+ );
+ }
+ else if (isset($details['version']))
+ {
+ $detail = array(
+ 'type' => 'version',
+ 'icon' => 'icon-flow-branch',
+ 'text' => $details['version']
+ );
+ }
+ else if (isset($details['result']))
+ {
+ $detail = array(
+ 'type' => 'error',
+ 'icon' => 'icon-block',
+ 'text' => $details['result']
+ );
+ }
+
+ // Format our data before send
+ // This data will be manipulate by maintenance_sys.js
+ list($date, $hour) = explode(' ', $rows['occured_on']);
+ $data[] = array(
+ 'major_infos' => $major_infos,
+ 'id' => $rows['activity_id'],
+ 'object_icon' => $object_icon,
+ 'object' => ucwords($object),
+ 'action_icon' => $action_icon,
+ 'action_color' => $action_color,
+ 'action' => $action,
+ 'user_id' => $rows['performed_by'],
+ 'username' => $rows['username'],
+ 'date' => format_date($date),
+ 'hour' => $hour,
+ 'detail' => $detail
+ );
+ }
+
+ // Now we good to send our response data
+ $response = array(
+ 'data' => $data,
+ );
+ echo json_encode($response);
+ exit;
+ }
+}
+else
+{
+ $page['warnings'][] = str_replace('%s', l10n('user_status_webmaster'), l10n('%s status is required to edit parameters.'));
+}
+
+// +-----------------------------------------------------------------------+
+// | template init |
+// +-----------------------------------------------------------------------+
+
+$template->assign('isWebmaster', (is_webmaster()) ? 1 : 0);
+$template->set_filenames(array('maintenance'=>'maintenance_sys.tpl'));
+
+// +-----------------------------------------------------------------------+
+// | sending html code |
+// +-----------------------------------------------------------------------+
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'maintenance');
+?>
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/menubar.php b/Piwingo/piwigo-data/piwigo/admin/menubar.php
new file mode 100644
index 0000000..58aaf68
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/menubar.php
@@ -0,0 +1,167 @@
+$pos)
+ {
+ $orders[$id] = $step * ($pos<0 ? -$crt : $crt);
+ $crt++;
+ }
+}
+
+include_once(PHPWG_ROOT_PATH.'include/block.class.php');
+
+// +-----------------------------------------------------------------------+
+// | tabs |
+// +-----------------------------------------------------------------------+
+
+include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
+
+$my_base_url = get_root_url().'admin.php?page=';
+
+$tabsheet = new tabsheet();
+$tabsheet->set_id('menus');
+$tabsheet->select('');
+$tabsheet->assign();
+
+
+$menu = new BlockManager('menubar');
+$menu->load_registered_blocks();
+$reg_blocks = $menu->get_registered_blocks();
+
+$mb_conf = @$conf[ 'blk_'.$menu->get_id() ];
+if ( is_string($mb_conf) )
+ $mb_conf = unserialize( $mb_conf );
+if ( !is_array($mb_conf) )
+ $mb_conf=array();
+
+foreach ($mb_conf as $id => $pos)
+{
+ if (!isset($reg_blocks[$id]))
+ unset($mb_conf[$id]);
+}
+
+$idx=1;
+foreach ($reg_blocks as $id => $block)
+{
+ if ( !isset($mb_conf[$id]) )
+ $mb_conf[$id] = $idx*50;
+ $idx++;
+}
+
+
+if ( isset($_POST['submit']) and is_webmaster())
+{
+ foreach ( $mb_conf as $id => $pos )
+ {
+ $hide = isset($_POST['hide_'.$id]);
+ $mb_conf[$id] = ($hide ? -1 : +1)*abs($pos);
+
+ $pos = (int)@$_POST['pos_'.$id];
+ if ($pos>0)
+ $mb_conf[$id] = $mb_conf[$id] > 0 ? $pos : -$pos;
+ }
+ make_consecutive( $mb_conf );
+
+ // BEGIN OPTIM - DONT ASK ABOUT THIS ALGO - but optimizes the size of the array we save in DB
+ /* !!! OPTIM DISABLED UNTIL IT HAS BEEN FIXED !!!
+ $reg_keys = array_keys($reg_blocks);
+ $cnf_keys = array_keys($mb_conf);
+ $best_slice = array( 'len'=>0 );
+ for ($i=0; $i$best_slice['len'])
+ {
+ $best_slice['len'] = 1+$k;
+ $best_slice['start_cnf'] = $j;
+ }
+ }
+ else
+ break;
+ }
+ }
+ }
+ */
+ $mb_conf_db = $mb_conf;
+ /*
+ if ($best_slice['len'])
+ {
+ for ($j=0; $j<$best_slice['start_cnf']; $j++ )
+ {
+ $sign = $mb_conf_db[ $cnf_keys[$j] ] > 0 ? 1 : -1;
+ $mb_conf_db[ $cnf_keys[$j] ] = $sign * ( ($best_slice['start_cnf'])*50 - ($best_slice['start_cnf']-$j) );
+ }
+ for ($j=$best_slice['start_cnf']; $j<$best_slice['start_cnf']+$best_slice['len']; $j++ )
+ {
+ if ($mb_conf_db[ $cnf_keys[$j] ] > 0)
+ unset( $mb_conf_db[ $cnf_keys[$j] ] );
+ }
+ }
+ //var_export( $best_slice ); var_export($mb_conf); var_export($mb_conf_db);
+ // END OPTIM
+ */
+ $query = '
+UPDATE '.CONFIG_TABLE.'
+ SET value=\''.addslashes(serialize($mb_conf_db)).'\'
+ WHERE param=\'blk_'.addslashes($menu->get_id()).'\'
+ ';
+ pwg_query($query);
+
+ $template->assign(
+ array(
+ 'save_success' => l10n('Order of menubar items has been updated successfully.'),
+ )
+ );
+
+}
+
+make_consecutive( $mb_conf );
+
+foreach ($mb_conf as $id => $pos )
+{
+ $template->append( 'blocks',
+ array(
+ 'pos' => $pos/5,
+ 'reg' => $reg_blocks[$id]
+ )
+ );
+}
+
+$action = get_root_url().'admin.php?page=menubar';
+$template->assign(array('F_ACTION'=>$action));
+
+$template->assign('isWebmaster', (is_webmaster()) ? 1 : 0);
+$template->assign('ADMIN_PAGE_TITLE', l10n('Menu Management'));
+
+$template->set_filename( 'menubar_admin_content', 'menubar.tpl' );
+$template->assign_var_from_handle( 'ADMIN_CONTENT', 'menubar_admin_content');
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/notification_by_mail.php b/Piwingo/piwigo-data/piwigo/admin/notification_by_mail.php
new file mode 100644
index 0000000..17d126d
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/notification_by_mail.php
@@ -0,0 +1,739 @@
+ 0)
+ {
+ $inserts = array();
+ $check_key_list = array();
+
+ while ($nbm_user = pwg_db_fetch_assoc($result))
+ {
+ // Calculate key
+ $nbm_user['check_key'] = find_available_check_key();
+
+ // Save key
+ $check_key_list[] = $nbm_user['check_key'];
+
+ // Insert new nbm_users
+ $inserts[] = array(
+ 'user_id' => $nbm_user['user_id'],
+ 'check_key' => $nbm_user['check_key'],
+ 'enabled' => 'false' // By default if false, set to true with specific functions
+ );
+
+ $page['infos'][] = l10n(
+ 'User %s [%s] added.',
+ stripslashes($nbm_user['username']),
+ $nbm_user['mail_address']
+ );
+ }
+
+ // Insert new nbm_users
+ mass_inserts(USER_MAIL_NOTIFICATION_TABLE, array('user_id', 'check_key', 'enabled'), $inserts);
+ // Update field enabled with specific function
+ $check_key_treated = do_subscribe_unsubscribe_notification_by_mail
+ (
+ true,
+ $conf['nbm_default_value_user_enabled'],
+ $check_key_list
+ );
+
+ // On timeout simulate like tabsheet send
+ if ($env_nbm['is_sendmail_timeout'])
+ {
+ $quoted_check_key_list = quote_check_key_list(array_diff($check_key_list, $check_key_treated));
+ if (count($quoted_check_key_list) != 0 )
+ {
+ $query = 'delete from '.USER_MAIL_NOTIFICATION_TABLE.' where check_key in ('.implode(",", $quoted_check_key_list).');';
+ $result = pwg_query($query);
+
+ redirect($base_url.get_query_string_diff(array(), false), l10n('Operation in progress')."\n".l10n('Please wait...'));
+ }
+ }
+ }
+}
+
+/*
+ * Apply global functions to mail content
+ * return customize mail content rendered
+ */
+function render_global_customize_mail_content($customize_mail_content)
+{
+ global $conf;
+
+ if ($conf['nbm_send_html_mail'] and !(strpos($customize_mail_content, '<') === 0))
+ {
+ // On HTML mail, detects if the content are HTML format.
+ // If it's plain text format, convert content to readable HTML
+ return nl2br(htmlspecialchars($customize_mail_content));
+ }
+ else
+ {
+ return $customize_mail_content;
+ }
+}
+
+/*
+ * Send mail for notification to all users
+ * Return list of "selected" users for 'list_to_send'
+ * Return list of "treated" check_key for 'send'
+ */
+function do_action_send_mail_notification($action = 'list_to_send', $check_key_list = array(), $customize_mail_content = '')
+{
+ global $conf, $page, $user, $lang_info, $lang, $env_nbm;
+ $return_list = array();
+
+ if (in_array($action, array('list_to_send', 'send')))
+ {
+ list($dbnow) = pwg_db_fetch_row(pwg_query('SELECT NOW();'));
+
+ $is_action_send = ($action == 'send');
+
+ // disabled and null mail_address are not selected in the list
+ $data_users = get_user_notifications('send', $check_key_list);
+
+ // List all if it's define on options or on timeout
+ $is_list_all_without_test = ($env_nbm['is_sendmail_timeout'] or $conf['nbm_list_all_enabled_users_to_send']);
+
+ // Check if exist news to list user or send mails
+ if ((!$is_list_all_without_test) or ($is_action_send))
+ {
+ if (count($data_users) > 0)
+ {
+ $datas = array();
+
+ if (!isset($customize_mail_content))
+ {
+ $customize_mail_content = $conf['nbm_complementary_mail_content'];
+ }
+
+ $customize_mail_content =
+ trigger_change('nbm_render_global_customize_mail_content', $customize_mail_content);
+
+
+ // Prepare message after change language
+ if ($is_action_send)
+ {
+ $msg_break_timeout = l10n('Time to send mail is limited. Others mails are skipped.');
+ }
+ else
+ {
+ $msg_break_timeout = l10n('Prepared time for list of users to send mail is limited. Others users are not listed.');
+ }
+
+ // Begin nbm users environment
+ begin_users_env_nbm($is_action_send);
+
+ foreach ($data_users as $nbm_user)
+ {
+ if ((!$is_action_send) and check_sendmail_timeout())
+ {
+ // Stop fill list on 'list_to_send', if the quota is override
+ $page['infos'][] = $msg_break_timeout;
+ break;
+ }
+ if (($is_action_send) and check_sendmail_timeout())
+ {
+ // Stop fill list on 'send', if the quota is override
+ $page['errors'][] = $msg_break_timeout;
+ break;
+ }
+
+ // set env nbm user
+ set_user_on_env_nbm($nbm_user, $is_action_send);
+
+ if ($is_action_send)
+ {
+ $auth = null;
+ $add_url_params = array();
+
+ $auth_key = create_user_auth_key($nbm_user['user_id'], $nbm_user['status']);
+
+ if ($auth_key !== false)
+ {
+ $auth = $auth_key['auth_key'];
+ $add_url_params['auth'] = $auth;
+ }
+
+ set_make_full_url();
+ // Fill return list of "treated" check_key for 'send'
+ $return_list[] = $nbm_user['check_key'];
+
+ if ($conf['nbm_send_detailed_content'])
+ {
+ $news = news($nbm_user['last_send'], $dbnow, false, $conf['nbm_send_html_mail'], $auth);
+ $exist_data = count($news) > 0;
+ }
+ else
+ {
+ $exist_data = news_exists($nbm_user['last_send'], $dbnow);
+ }
+
+ if ($exist_data)
+ {
+ $subject = '['.$conf['gallery_title'].'] '.l10n('New photos added');
+
+ // Assign current var for nbm mail
+ assign_vars_nbm_mail_content($nbm_user);
+
+ if (!is_null($nbm_user['last_send']))
+ {
+ $env_nbm['mail_template']->assign
+ (
+ 'content_new_elements_between',
+ array
+ (
+ 'DATE_BETWEEN_1' => $nbm_user['last_send'],
+ 'DATE_BETWEEN_2' => $dbnow,
+ )
+ );
+ }
+ else
+ {
+ $env_nbm['mail_template']->assign
+ (
+ 'content_new_elements_single',
+ array
+ (
+ 'DATE_SINGLE' => $dbnow,
+ )
+ );
+ }
+
+ if ($conf['nbm_send_detailed_content'])
+ {
+ $env_nbm['mail_template']->assign('global_new_lines', $news);
+ }
+
+ $nbm_user_customize_mail_content =
+ trigger_change('nbm_render_user_customize_mail_content',
+ $customize_mail_content, $nbm_user);
+ if (!empty($nbm_user_customize_mail_content))
+ {
+ $env_nbm['mail_template']->assign
+ (
+ 'custom_mail_content', $nbm_user_customize_mail_content
+ );
+ }
+
+ if ($conf['nbm_send_html_mail'] and $conf['nbm_send_recent_post_dates'])
+ {
+ $recent_post_dates = get_recent_post_dates_array(
+ $conf['recent_post_dates']['NBM']);
+ foreach ($recent_post_dates as $date_detail)
+ {
+ $env_nbm['mail_template']->append
+ (
+ 'recent_posts',
+ array
+ (
+ 'TITLE' => get_title_recent_post_date($date_detail),
+ 'HTML_DATA' => get_html_description_recent_post_date($date_detail, $auth)
+ )
+ );
+ }
+ }
+
+ $env_nbm['mail_template']->assign
+ (
+ array
+ (
+ 'GOTO_GALLERY_TITLE' => $conf['gallery_title'],
+ 'GOTO_GALLERY_URL' => add_url_params(get_gallery_home_url(), $add_url_params),
+ 'SEND_AS_NAME' => $env_nbm['send_as_name'],
+ )
+ );
+
+ $ret = pwg_mail(
+ array(
+ 'name' => stripslashes($nbm_user['username']),
+ 'email' => $nbm_user['mail_address'],
+ ),
+ array(
+ 'from' => $env_nbm['send_as_mail_formated'],
+ 'subject' => $subject,
+ 'email_format' => $env_nbm['email_format'],
+ 'content' => $env_nbm['mail_template']->parse('notification_by_mail', true),
+ 'content_format' => $env_nbm['email_format'],
+ 'auth_key' => $auth,
+ )
+ );
+
+ if ($ret)
+ {
+ inc_mail_sent_success($nbm_user);
+
+ $datas[] = array(
+ 'user_id' => $nbm_user['user_id'],
+ 'last_send' => $dbnow
+ );
+ }
+ else
+ {
+ inc_mail_sent_failed($nbm_user);
+ }
+
+ unset_make_full_url();
+ }
+ }
+ else
+ {
+ if (news_exists($nbm_user['last_send'], $dbnow))
+ {
+ // Fill return list of "selected" users for 'list_to_send'
+ $return_list[] = $nbm_user;
+ }
+ }
+
+ // unset env nbm user
+ unset_user_on_env_nbm();
+ }
+
+ // Restore nbm environment
+ end_users_env_nbm();
+
+ if ($is_action_send)
+ {
+ mass_updates(
+ USER_MAIL_NOTIFICATION_TABLE,
+ array(
+ 'primary' => array('user_id'),
+ 'update' => array('last_send')
+ ),
+ $datas
+ );
+
+ display_counter_info();
+ }
+ }
+ else
+ {
+ if ($is_action_send)
+ {
+ $page['errors'][] = l10n('No user to send notifications by mail.');
+ }
+ }
+ }
+ else
+ {
+ // Quick List, don't check news
+ // Fill return list of "selected" users for 'list_to_send'
+ $return_list = $data_users;
+ }
+ }
+
+ // Return list of "selected" users for 'list_to_send'
+ // Return list of "treated" check_key for 'send'
+ return $return_list;
+}
+
+// +-----------------------------------------------------------------------+
+// | Main |
+// +-----------------------------------------------------------------------+
+if (!isset($_GET['mode']))
+{
+ $page['mode'] = 'send';
+}
+else
+{
+ $page['mode'] = $_GET['mode'];
+}
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok |
+// +-----------------------------------------------------------------------+
+check_status(get_tab_status($page['mode']));
+
+
+// +-----------------------------------------------------------------------+
+// | Add event handler |
+// +-----------------------------------------------------------------------+
+add_event_handler('nbm_render_global_customize_mail_content', 'render_global_customize_mail_content');
+trigger_notify('nbm_event_handler_added');
+
+
+// +-----------------------------------------------------------------------+
+// | Insert new users with mails |
+// +-----------------------------------------------------------------------+
+if (!isset($_POST) or (count($_POST) ==0))
+{
+ // No insert data in post mode
+ insert_new_data_user_mail_notification();
+}
+
+// +-----------------------------------------------------------------------+
+// | Treatment of tab post |
+// +-----------------------------------------------------------------------+
+
+if (!empty($_POST))
+{
+ check_pwg_token();
+}
+
+switch ($page['mode'])
+{
+ case 'param' :
+ {
+ if (isset($_POST['param_submit']))
+ {
+ $_POST['nbm_send_mail_as'] = strip_tags($_POST['nbm_send_mail_as']);
+
+ check_input_parameter('nbm_send_html_mail', $_POST, false, '/^(true|false)$/');
+ check_input_parameter('nbm_send_detailed_content', $_POST, false, '/^(true|false)$/');
+ check_input_parameter('nbm_send_recent_post_dates', $_POST, false, '/^(true|false)$/');
+
+ $updated_param_count = 0;
+ // Update param
+ $result = pwg_query('select param, value from '.CONFIG_TABLE.' where param like \'nbm\\_%\'');
+ while ($nbm_user = pwg_db_fetch_assoc($result))
+ {
+ if (isset($_POST[$nbm_user['param']]))
+ {
+ conf_update_param($nbm_user['param'], $_POST[$nbm_user['param']], true);
+ $updated_param_count++;
+ }
+ }
+
+ $template->assign(
+ array(
+ 'save_success' => l10n_dec(
+ '%d parameter was updated.', '%d parameters were updated.',
+ $updated_param_count
+ )
+ )
+ );
+ }
+ }
+ case 'subscribe' :
+ {
+ if (isset($_POST['falsify']) and isset($_POST['cat_true']))
+ {
+ $check_key_treated = unsubscribe_notification_by_mail(true, $_POST['cat_true']);
+ do_timeout_treatment('cat_true', $check_key_treated);
+ }
+ else
+ if (isset($_POST['trueify']) and isset($_POST['cat_false']))
+ {
+ $check_key_treated = subscribe_notification_by_mail(true, $_POST['cat_false']);
+ do_timeout_treatment('cat_false', $check_key_treated);
+ }
+ break;
+ }
+
+ case 'send' :
+ {
+ if (isset($_POST['send_submit']) and isset($_POST['send_selection']) and isset($_POST['send_customize_mail_content']))
+ {
+ $check_key_treated = do_action_send_mail_notification('send', $_POST['send_selection'], stripslashes($_POST['send_customize_mail_content']));
+ do_timeout_treatment('send_selection', $check_key_treated);
+ }
+ }
+}
+
+// +-----------------------------------------------------------------------+
+// | template initialization |
+// +-----------------------------------------------------------------------+
+$template->set_filenames
+(
+ array
+ (
+ 'double_select' => 'double_select.tpl',
+ 'notification_by_mail'=>'notification_by_mail.tpl'
+ )
+);
+
+$template->assign
+(
+ array
+ (
+ 'PWG_TOKEN' => get_pwg_token(),
+ 'U_HELP' => get_root_url().'admin/popuphelp.php?page=notification_by_mail',
+ 'F_ACTION'=> $base_url.get_query_string_diff(array())
+ )
+);
+
+if (is_autorize_status(ACCESS_WEBMASTER))
+{
+ // TabSheet
+ $tabsheet = new tabsheet();
+ $tabsheet->set_id('nbm');
+ $tabsheet->select($page['mode']);
+ $tabsheet->assign();
+}
+
+if ($must_repost)
+{
+ // Get name of submit button
+ $repost_submit_name = '';
+ if (isset($_POST['falsify']))
+ {
+ $repost_submit_name = 'falsify';
+ }
+ elseif (isset($_POST['trueify']))
+ {
+ $repost_submit_name = 'trueify';
+ }
+ elseif (isset($_POST['send_submit']))
+ {
+ $repost_submit_name = 'send_submit';
+ }
+
+ $template->assign('REPOST_SUBMIT_NAME', $repost_submit_name);
+}
+
+switch ($page['mode'])
+{
+ case 'param' :
+ {
+ $template->assign(
+ $page['mode'],
+ array(
+ 'SEND_HTML_MAIL' => $conf['nbm_send_html_mail'],
+ 'SEND_MAIL_AS' => $conf['nbm_send_mail_as'],
+ 'SEND_DETAILED_CONTENT' => $conf['nbm_send_detailed_content'],
+ 'COMPLEMENTARY_MAIL_CONTENT' => $conf['nbm_complementary_mail_content'],
+ 'SEND_RECENT_POST_DATES' => $conf['nbm_send_recent_post_dates'],
+ ));
+ break;
+ }
+
+ case 'subscribe' :
+ {
+ $template->assign( $page['mode'], true );
+
+ $template->assign(
+ array(
+ 'L_CAT_OPTIONS_TRUE' => l10n('Subscribed'),
+ 'L_CAT_OPTIONS_FALSE' => l10n('Unsubscribed')
+ )
+ );
+
+ $data_users = get_user_notifications('subscribe');
+
+ $opt_true = array();
+ $opt_true_selected = array();
+ $opt_false = array();
+ $opt_false_selected = array();
+ foreach ($data_users as $nbm_user)
+ {
+ if (get_boolean($nbm_user['enabled']))
+ {
+ $opt_true[ $nbm_user['check_key'] ] = stripslashes($nbm_user['username']).'['.$nbm_user['mail_address'].']';
+ if ((isset($_POST['falsify']) and isset($_POST['cat_true']) and in_array($nbm_user['check_key'], $_POST['cat_true'])))
+ {
+ $opt_true_selected[] = $nbm_user['check_key'];
+ }
+ }
+ else
+ {
+ $opt_false[ $nbm_user['check_key'] ] = stripslashes($nbm_user['username']).'['.$nbm_user['mail_address'].']';
+ if (isset($_POST['trueify']) and isset($_POST['cat_false']) and in_array($nbm_user['check_key'], $_POST['cat_false']))
+ {
+ $opt_false_selected[] = $nbm_user['check_key'];
+ }
+ }
+ }
+ $template->assign( array(
+ 'category_option_true' => $opt_true,
+ 'category_option_true_selected' => $opt_true_selected,
+ 'category_option_false' => $opt_false,
+ 'category_option_false_selected' => $opt_false_selected,
+ )
+ );
+ $template->assign_var_from_handle('DOUBLE_SELECT', 'double_select');
+ break;
+ }
+
+ case 'send' :
+ {
+ $tpl_var = array('users'=> array() );
+
+ $data_users = do_action_send_mail_notification('list_to_send');
+
+ $tpl_var['CUSTOMIZE_MAIL_CONTENT'] =
+ isset($_POST['send_customize_mail_content'])
+ ? stripslashes($_POST['send_customize_mail_content'])
+ : $conf['nbm_complementary_mail_content'];
+
+ if (count($data_users))
+ {
+ foreach ($data_users as $nbm_user)
+ {
+ if (
+ (!$must_repost) or // Not timeout, normal treatment
+ (($must_repost) and in_array($nbm_user['check_key'], $_POST['send_selection'])) // Must be repost, show only user to send
+ )
+ {
+ $tpl_var['users'][] =
+ array(
+ 'ID' => $nbm_user['check_key'],
+ 'CHECKED' => ( // not check if not selected, on init select stripslashes($nbm_user['username']),
+ 'EMAIL' => $nbm_user['mail_address'],
+ 'LAST_SEND'=> $nbm_user['last_send']
+ );
+ }
+ }
+ }
+ $template->assign($page['mode'], $tpl_var);
+
+ if ($conf['auth_key_duration'] > 0)
+ {
+ $template->assign(
+ 'auth_key_duration',
+ time_since(
+ strtotime('now -'.$conf['auth_key_duration'].' second'),
+ 'second',
+ null,
+ false
+ )
+ );
+ }
+
+ break;
+ }
+}
+
+$template->assign('ADMIN_PAGE_TITLE', l10n('Send mail to users'));
+
+// +-----------------------------------------------------------------------+
+// | Sending html code |
+// +-----------------------------------------------------------------------+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'notification_by_mail');
+
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/permalinks.php b/Piwingo/piwigo-data/piwigo/admin/permalinks.php
new file mode 100644
index 0000000..03cf395
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/permalinks.php
@@ -0,0 +1,190 @@
+ $value)
+ {
+ if (!in_array($key, $get_rejects) and $key!=$get_param)
+ {
+ $base_url .= $is_first ? '?' : '&';
+ $is_first = false;
+
+ if (!in_array($key, array('page', 'psf', 'dpsf', 'pwg_token')))
+ {
+ fatal_error('unexpected URL get key');
+ }
+
+ $base_url .= urlencode($key).'='.urlencode($value);
+ }
+ }
+
+ $ret = array();
+ foreach( $sortable_by as $field)
+ {
+ $url = $base_url;
+ $disp = '↓'; // TODO: an small image is better
+
+ if ( $field !== @$_GET[$get_param] )
+ {
+ if ( !isset($default_field) or $default_field!=$field )
+ { // the first should be the default
+ $url = add_url_params($url, array($get_param=>$field) );
+ }
+ elseif (isset($default_field) and !isset($_GET[$get_param]) )
+ {
+ $ret[] = $field;
+ $disp = ''.$disp.'';
+ }
+ }
+ else
+ {
+ $ret[] = $field;
+ $disp = ''.$disp.'';
+ }
+ if ( isset($template_var) )
+ {
+ $template->assign( $template_var.strtoupper($field),
+ ''.$disp.''
+ );
+ }
+ }
+ return $ret;
+}
+
+if (!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
+
+include_once(PHPWG_ROOT_PATH.'admin/include/functions_permalinks.php');
+
+check_input_parameter('cat_id', $_POST, false, PATTERN_ID);
+
+$selected_cat = array();
+if ( isset($_POST['set_permalink']) and $_POST['cat_id']>0 )
+{
+ check_pwg_token();
+ $permalink = $_POST['permalink'];
+ if ( empty($permalink) )
+ delete_cat_permalink($_POST['cat_id'], isset($_POST['save']) );
+ else
+ set_cat_permalink($_POST['cat_id'], $permalink, isset($_POST['save']) );
+ $selected_cat = array( $_POST['cat_id'] );
+}
+elseif ( isset($_GET['delete_permanent']) )
+{
+ check_pwg_token();
+ $query = '
+DELETE FROM '.OLD_PERMALINKS_TABLE.'
+ WHERE permalink=\''.pwg_db_real_escape_string($_GET['delete_permanent']).'\'
+ LIMIT 1';
+ $result = pwg_query($query);
+ if (pwg_db_changes($result)==0)
+ {
+ $page['errors'][] = l10n('Cannot delete the old permalink !');
+ }
+}
+
+
+$template->set_filename('permalinks', 'permalinks.tpl' );
+
+// +-----------------------------------------------------------------------+
+// | tabs |
+// +-----------------------------------------------------------------------+
+
+$page['tab'] = 'permalinks';
+include(PHPWG_ROOT_PATH.'admin/include/albums_tab.inc.php');
+
+
+$query = '
+SELECT
+ id, permalink,
+ CONCAT(id, " - ", name, IF(permalink IS NULL, "", " √") ) AS name,
+ uppercats, global_rank
+FROM '.CATEGORIES_TABLE;
+
+display_select_cat_wrapper( $query, $selected_cat, 'categories', false );
+
+$pwg_token = get_pwg_token();
+
+// --- generate display of active permalinks -----------------------------------
+$sort_by = parse_sort_variables(
+ array('id', 'name', 'permalink'), 'name',
+ 'psf',
+ array('delete_permanent'),
+ 'SORT_' );
+
+$query = '
+SELECT id, permalink, uppercats, global_rank
+ FROM '.CATEGORIES_TABLE.'
+ WHERE permalink IS NOT NULL
+';
+if ( $sort_by[0]=='id' or $sort_by[0]=='permalink' )
+{
+ $query .= ' ORDER BY '.$sort_by[0];
+}
+$categories=array();
+$result=pwg_query($query);
+while ( $row = pwg_db_fetch_assoc($result) )
+{
+ $row['name'] = get_cat_display_name_cache( $row['uppercats'] );
+ $categories[] = $row;
+}
+
+if ( $sort_by[0]=='name')
+{
+ usort($categories, 'global_rank_compare');
+}
+$template->assign( 'permalinks', $categories );
+
+// --- generate display of old permalinks --------------------------------------
+
+$sort_by = parse_sort_variables(
+ array('cat_id','permalink','date_deleted','last_hit','hit'), null,
+ 'dpsf',
+ array('delete_permanent'),
+ 'SORT_OLD_', '#old_permalinks' );
+
+$url_del_base = get_root_url().'admin.php?page=permalinks';
+$query = 'SELECT * FROM '.OLD_PERMALINKS_TABLE;
+if ( count($sort_by) )
+{
+ $query .= ' ORDER BY '.$sort_by[0];
+}
+$result = pwg_query($query);
+$deleted_permalinks=array();
+while ( $row = pwg_db_fetch_assoc($result) )
+{
+ $row['name'] = get_cat_display_name_cache($row['cat_id']);
+ $row['U_DELETE'] =
+ add_url_params(
+ $url_del_base,
+ array('delete_permanent'=> $row['permalink'],'pwg_token'=>$pwg_token)
+ );
+ $deleted_permalinks[] = $row;
+}
+
+$template->assign(array(
+ 'PWG_TOKEN' => $pwg_token,
+ 'U_HELP' => get_root_url().'admin/popuphelp.php?page=permalinks',
+ 'deleted_permalinks' => $deleted_permalinks,
+ 'ADMIN_PAGE_TITLE' => l10n('Albums'),
+ ));
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'permalinks');
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/photo.php b/Piwingo/piwigo-data/piwigo/admin/photo.php
new file mode 100644
index 0000000..f20b1d6
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/photo.php
@@ -0,0 +1,82 @@
+set_id('photo');
+$tabsheet->select($page['tab']);
+$tabsheet->assign();
+
+$template->assign(
+ array(
+ 'ADMIN_PAGE_TITLE' => l10n('Edit photo').' #'.$_GET['image_id'].'',
+ )
+ );
+
+// +-----------------------------------------------------------------------+
+// | Load the tab |
+// +-----------------------------------------------------------------------+
+
+if ('properties' == $page['tab'])
+{
+ include(PHPWG_ROOT_PATH.'admin/picture_modify.php');
+}
+elseif ('coi' == $page['tab'])
+{
+ include(PHPWG_ROOT_PATH.'admin/picture_coi.php');
+}
+elseif ('formats' == $page['tab'] && $conf['enable_formats'])
+{
+ include(PHPWG_ROOT_PATH.'admin/picture_formats.php');
+}
+else
+{
+ include(PHPWG_ROOT_PATH.'admin/photo_'.$page['tab'].'.php');
+}
+?>
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/photos_add.php b/Piwingo/piwigo-data/piwigo/admin/photos_add.php
new file mode 100644
index 0000000..b1d589d
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/photos_add.php
@@ -0,0 +1,74 @@
+set_id('photos_add');
+$tabsheet->select($page['tab']);
+$tabsheet->assign();
+
+// +-----------------------------------------------------------------------+
+// | template init |
+// +-----------------------------------------------------------------------+
+
+$template->set_filenames(
+ array(
+ 'photos_add' => 'photos_add_'.$page['tab'].'.tpl'
+ )
+ );
+
+// +-----------------------------------------------------------------------+
+// | Load the tab |
+// +-----------------------------------------------------------------------+
+
+include(PHPWG_ROOT_PATH.'admin/photos_add_'.$page['tab'].'.php');
+?>
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/photos_add_applications.php b/Piwingo/piwigo-data/piwigo/admin/photos_add_applications.php
new file mode 100644
index 0000000..efe1a31
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/photos_add_applications.php
@@ -0,0 +1,25 @@
+assign('ADMIN_PAGE_TITLE', l10n('Upload Photos'));
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'photos_add');
+?>
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/photos_add_direct.php b/Piwingo/piwigo-data/piwigo/admin/photos_add_direct.php
new file mode 100644
index 0000000..21fc3e3
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/photos_add_direct.php
@@ -0,0 +1,164 @@
+ $user['id'],
+ 'element_id' => $image_id,
+ );
+ }
+ mass_inserts(
+ CADDIE_TABLE,
+ array_keys($inserts[0]),
+ $inserts
+ );
+
+ redirect(get_root_url().'admin.php?page=batch_manager&filter=prefilter-caddie');
+}
+
+if (userprefs_get_param('promote-mobile-apps', true))
+{
+ $query = '
+SELECT registration_date
+ FROM '.USER_INFOS_TABLE.'
+ WHERE registration_date IS NOT NULL
+ ORDER BY user_id ASC
+ LIMIT 1
+;';
+ list($register_date) = pwg_db_fetch_row(pwg_query($query));
+
+ $query = '
+SELECT COUNT(*)
+ FROM '.CATEGORIES_TABLE.'
+;';
+ list($nb_cats) = pwg_db_fetch_row(pwg_query($query));
+
+ $query = '
+SELECT COUNT(*)
+ FROM '.IMAGES_TABLE.'
+;';
+ list($nb_images) = pwg_db_fetch_row(pwg_query($query));
+
+ include_once(PHPWG_ROOT_PATH.'include/mdetect.php');
+ $uagent_obj = new uagent_info();
+ // To see the mobile app promote, the account must have 2 weeks ancient, 3 albums created and 30 photos uploaded
+ $template->assign("PROMOTE_MOBILE_APPS", (!$uagent_obj->DetectIos() and strtotime($register_date) < strtotime('2 weeks ago') and $nb_cats >= 3 and $nb_images >= 30));
+}
+else
+{
+ $template->assign("PROMOTE_MOBILE_APPS", false);
+}
+
+$template->assign('PHPWG_URL', PHPWG_URL);
+
+// +-----------------------------------------------------------------------+
+// | Formats Mode |
+// +-----------------------------------------------------------------------+
+
+$display_formats = $conf['enable_formats'] && isset($_GET['formats']);
+
+$have_formats_original = false;
+$formats_original_info = array();
+$formats_ext_info = null;
+
+// If URL parameter isn't empty
+if ($display_formats && $_GET['formats'])
+{
+ check_input_parameter('formats', $_GET, false, PATTERN_ID, false);
+
+ $formats_original_info = get_image_infos($_GET['formats']);
+ if ($formats_original_info)
+ {
+ $src_image = new SrcImage($formats_original_info);
+
+ $formats_original_info['src'] = DerivativeImage::url(IMG_SQUARE, $src_image);
+
+ // Fetch actual formats
+ $query = '
+SELECT *
+ FROM '.IMAGE_FORMAT_TABLE.'
+ WHERE image_id = '.$formats_original_info['id'].'
+;';
+ $formats = query2array($query);
+
+ if (!empty($formats))
+ {
+ $format_strings = array();
+ $formats_exts = array();
+
+ foreach ($formats as $format)
+ {
+ $format_strings[] = sprintf('%s (%.2fMB)', $format['ext'], $format['filesize']/1024);
+ $formats_exts[] = strtolower($format['ext']);
+ }
+
+ $formats_original_info['formats'] = l10n('Formats: %s', implode(', ', $format_strings));
+ $formats_ext_info = json_encode($formats_exts);
+ }
+
+ $extTab = explode('.',$formats_original_info['file']);
+
+ $formats_original_info['ext'] = l10n('%s file type',strtoupper(end($extTab)));
+
+ $formats_original_info['u_edit'] = get_root_url().'admin.php?page=photo-'.$formats_original_info['id'];
+
+ $have_formats_original = true;
+ }
+ else
+ {
+ $page['errors'][] = l10n('The original picture selected dosen\'t exists.');
+ }
+
+}
+
+// +-----------------------------------------------------------------------+
+// | prepare form |
+// +-----------------------------------------------------------------------+
+
+include_once(PHPWG_ROOT_PATH.'admin/include/photos_add_direct_prepare.inc.php');
+
+// +-----------------------------------------------------------------------+
+// | sending html code |
+// +-----------------------------------------------------------------------+
+
+trigger_notify('loc_end_photo_add_direct');
+
+$template->assign(array(
+ 'ENABLE_FORMATS' => $conf['enable_formats'],
+ 'DISPLAY_FORMATS' => $display_formats,
+ 'HAVE_FORMATS_ORIGINAL' => $have_formats_original,
+ 'FORMATS_ORIGINAL_INFO' => $formats_original_info,
+ 'FORMATS_EXT_INFO' => $formats_ext_info,
+ 'SWITCH_FORMAT_MODE_URL' => get_root_url().'admin.php?page=photos_add'.($display_formats ? '':'&formats'),
+ 'format_ext' => implode(',', $conf['format_ext']),
+ 'str_format_ext' => implode(', ', $conf['format_ext']),
+));
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'photos_add');
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/photos_add_ftp.php b/Piwingo/piwigo-data/piwigo/admin/photos_add_ftp.php
new file mode 100644
index 0000000..004242f
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/photos_add_ftp.php
@@ -0,0 +1,33 @@
+assign(
+ 'FTP_HELP_CONTENT',
+ load_language(
+ 'help/photos_add_ftp.html',
+ '',
+ array('return'=>true)
+ )
+ );
+
+// +-----------------------------------------------------------------------+
+// | sending html code |
+// +-----------------------------------------------------------------------+
+$template->assign('ADMIN_PAGE_TITLE', l10n('Upload Photos'));
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'photos_add');
+?>
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/picture_coi.php b/Piwingo/piwigo-data/piwigo/admin/picture_coi.php
new file mode 100644
index 0000000..96726b0
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/picture_coi.php
@@ -0,0 +1,98 @@
+sizing->max_crop != 0)
+ {
+ delete_element_derivatives($row, $params->type);
+ }
+ }
+ delete_element_derivatives($row, IMG_CUSTOM);
+ $uid = '&b='.time();
+ $conf['question_mark_in_urls'] = $conf['php_extension_in_urls'] = true;
+ if ($conf['derivative_url_style']==1)
+ {
+ $conf['derivative_url_style']=0; //auto
+ }
+}
+else
+{
+ $uid = '';
+}
+
+$tpl_var = array(
+ 'TITLE' => render_element_name($row),
+ 'ALT' => $row['file'],
+ 'U_IMG' => DerivativeImage::url(IMG_LARGE, $row),
+ );
+
+if (!empty($row['coi']))
+{
+ $tpl_var['coi'] = array(
+ 'l'=> char_to_fraction($row['coi'][0]),
+ 't'=> char_to_fraction($row['coi'][1]),
+ 'r'=> char_to_fraction($row['coi'][2]),
+ 'b'=> char_to_fraction($row['coi'][3]),
+ );
+}
+
+foreach(ImageStdParams::get_defined_type_map() as $params)
+{
+ if ($params->sizing->max_crop != 0)
+ {
+ $derivative = new DerivativeImage($params, new SrcImage($row) );
+ $template->append( 'cropped_derivatives', array(
+ 'U_IMG' => $derivative->get_url().$uid,
+ 'HTM_SIZE' => $derivative->get_size_htm(),
+ ) );
+ }
+}
+
+
+$template->assign($tpl_var);
+$template->set_filename('picture_coi', 'picture_coi.tpl');
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'picture_coi');
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/picture_formats.php b/Piwingo/piwigo-data/piwigo/admin/picture_formats.php
new file mode 100644
index 0000000..7aba309
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/picture_formats.php
@@ -0,0 +1,63 @@
+assign(array(
+ 'ADD_FORMATS_URL' => get_root_url().'admin.php?page=photos_add&formats='.$_GET['image_id'],
+ 'IMG_SQUARE_SRC' => DerivativeImage::url(ImageStdParams::get_by_type(IMG_SQUARE), $image),
+ 'FORMATS' => $formats,
+ 'PWG_TOKEN' => get_pwg_token(),
+));
+
+$template->set_filename('picture_formats', 'picture_formats.tpl');
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'picture_formats');
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/picture_modify.php b/Piwingo/piwigo-data/piwigo/admin/picture_modify.php
new file mode 100644
index 0000000..edf8845
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/picture_modify.php
@@ -0,0 +1,430 @@
+array(1,2)))));
+ }
+
+ redirect(make_index_url());
+}
+
+// +-----------------------------------------------------------------------+
+// | synchronize metadata |
+// +-----------------------------------------------------------------------+
+
+if (isset($_GET['sync_metadata']))
+{
+ sync_metadata(array( intval($_GET['image_id'])));
+ $page['infos'][] = l10n('Metadata synchronized from file');
+}
+
+//--------------------------------------------------------- update informations
+if (isset($_POST['submit']))
+{
+ check_pwg_token();
+
+ $data = array();
+ $data['id'] = $_GET['image_id'];
+ $data['level'] = $_POST['level'];
+
+ $to_sanitize_fields = array('name', 'author', 'comment');
+ foreach ($to_sanitize_fields as $field)
+ {
+ $data[$field] = $conf['allow_html_descriptions'] ? @$_POST[$field] : strip_tags(@$_POST[$field]);
+ }
+
+ if (!empty($_POST['date_creation']))
+ {
+ $data['date_creation'] = $_POST['date_creation'];
+ }
+ else
+ {
+ $data['date_creation'] = null;
+ }
+
+ $data = trigger_change('picture_modify_before_update', $data);
+
+ single_update(
+ IMAGES_TABLE,
+ $data,
+ array('id' => $data['id'])
+ );
+
+ // time to deal with tags
+ $tag_ids = array();
+ if (!empty($_POST['tags']))
+ {
+ $tag_ids = get_tag_ids($_POST['tags']);
+ }
+ set_tags($tag_ids, $_GET['image_id']);
+
+ // association to albums
+ if (!isset($_POST['associate']))
+ {
+ $_POST['associate'] = array();
+ }
+ check_input_parameter('associate', $_POST, true, PATTERN_ID);
+ move_images_to_categories(array($_GET['image_id']), $_POST['associate']);
+
+ invalidate_user_cache();
+
+ // thumbnail for albums
+ if (!isset($_POST['represent']))
+ {
+ $_POST['represent'] = array();
+ }
+ check_input_parameter('represent', $_POST, true, PATTERN_ID);
+
+ $no_longer_thumbnail_for = array_diff($represented_albums, $_POST['represent']);
+ if (count($no_longer_thumbnail_for) > 0)
+ {
+ set_random_representant($no_longer_thumbnail_for);
+ }
+
+ $new_thumbnail_for = array_diff($_POST['represent'], $represented_albums);
+ if (count($new_thumbnail_for) > 0)
+ {
+ $query = '
+UPDATE '.CATEGORIES_TABLE.'
+ SET representative_picture_id = '.$_GET['image_id'].'
+ WHERE id IN ('.implode(',', $new_thumbnail_for).')
+;';
+ pwg_query($query);
+ }
+
+ $represented_albums = $_POST['represent'];
+
+ $template->assign(
+ array(
+ 'save_success' => l10n('Photo informations updated'),
+ )
+ );
+
+ pwg_activity('photo', $_GET['image_id'], 'edit');
+
+ // refresh page cache
+ $page['image'] = get_image_infos($_GET['image_id'], true);
+}
+
+// tags
+$query = '
+SELECT
+ id,
+ name
+ FROM '.IMAGE_TAG_TABLE.' AS it
+ JOIN '.TAGS_TABLE.' AS t ON t.id = it.tag_id
+ WHERE image_id = '.$_GET['image_id'].'
+;';
+$tag_selection = get_taglist($query);
+
+$row = $page['image'];
+
+if (isset($data['date_creation']))
+{
+ $row['date_creation'] = $data['date_creation'];
+}
+
+$storage_category_id = null;
+if (!empty($row['storage_category_id']))
+{
+ $storage_category_id = $row['storage_category_id'];
+}
+
+$image_file = $row['file'];
+
+// +-----------------------------------------------------------------------+
+// | template init |
+// +-----------------------------------------------------------------------+
+
+$template->set_filenames(
+ array(
+ 'picture_modify' => 'picture_modify.tpl'
+ )
+ );
+
+$admin_url_start = $admin_photo_base_url.'-properties';
+
+$src_image = new SrcImage($row);
+
+// in case the photo needs a rotation of 90 degrees (clockwise or counterclockwise), we switch width and height
+if (in_array($row['rotation'], array(1, 3)))
+{
+ list($row['width'], $row['height']) = array($row['height'], $row['width']);
+}
+
+$template->assign(
+ array(
+ 'tag_selection' => $tag_selection,
+ 'U_DOWNLOAD' => 'action.php?id='.$_GET['image_id'].'&part=e&pwg_token='.get_pwg_token().'&download',
+ 'U_SYNC' => $admin_url_start.'&sync_metadata=1',
+ 'U_DELETE' => $admin_url_start.'&delete=1&pwg_token='.get_pwg_token(),
+ 'U_HISTORY' => get_root_url().'admin.php?page=history&filter_image_id='.$_GET['image_id'],
+ 'U_ACTIVITY' => get_root_url().'admin.php?page=user_activity&photo='.$_GET['image_id'],
+
+ 'PATH'=>$row['path'],
+
+ 'TN_SRC' => DerivativeImage::url(IMG_MEDIUM, $src_image),
+ 'FILE_SRC' => DerivativeImage::url(IMG_LARGE, $src_image),
+
+ 'NAME' =>
+ isset($_POST['name']) ?
+ stripslashes($_POST['name']) : @$row['name'],
+
+ 'TITLE' => render_element_name($row),
+
+ 'DIMENSIONS' => @$row['width'].' * '.@$row['height'],
+
+ 'FORMAT' => ($row['width'] >= $row['height'])? 1:0,//0:horizontal, 1:vertical
+
+ 'FILESIZE' => @$row['filesize'].' KB',
+
+ 'REGISTRATION_DATE' => format_date($row['date_available']),
+
+ 'AUTHOR' => htmlspecialchars(
+ isset($_POST['author'])
+ ? stripslashes($_POST['author'])
+ : (empty($row['author']) ? '' : $row['author'])
+ ),
+
+ 'DATE_CREATION' => $row['date_creation'],
+
+ 'DESCRIPTION' =>
+ htmlspecialchars( isset($_POST['comment']) ?
+ stripslashes($_POST['comment']) : (empty($row['comment']) ? '' : $row['comment'])),
+
+ 'F_ACTION' =>
+ get_root_url().'admin.php'
+ .get_query_string_diff(array('sync_metadata'))
+ )
+ );
+
+$added_by = 'N/A';
+$query = '
+SELECT '.$conf['user_fields']['username'].' AS username
+ FROM '.USERS_TABLE.'
+ WHERE '.$conf['user_fields']['id'].' = '.$row['added_by'].'
+;';
+$result = pwg_query($query);
+while ($user_row = pwg_db_fetch_assoc($result))
+{
+ $row['added_by'] = $user_row['username'];
+}
+
+$extTab = explode('.',$row['file']);
+
+$intro_vars = array(
+ 'file' => l10n('%s', $row['file']),
+ 'date' => l10n('Posted the %s', format_date($row['date_available'], array('day', 'month', 'year'))),
+ 'age' => l10n(ucfirst(time_since($row['date_available'], 'year'))),
+ 'added_by' => l10n('Added by %s', $row['added_by']),
+ 'size' => l10n('%s pixels, %.2f MB', $row['width'].'×'.$row['height'], $row['filesize']/1024),
+ 'stats' => l10n('Visited %d times', $row['hit']),
+ 'id' => l10n($row['id']),
+ 'ext' => l10n('%s file type',strtoupper(end($extTab))),
+ 'is_svg'=> (strtoupper(end($extTab)) == 'SVG'),
+ );
+
+if ($conf['rate'] and !empty($row['rating_score']))
+{
+ $query = '
+SELECT
+ COUNT(*)
+ FROM '.RATE_TABLE.'
+ WHERE element_id = '.$_GET['image_id'].'
+;';
+ list($row['nb_rates']) = pwg_db_fetch_row(pwg_query($query));
+
+ $intro_vars['stats'].= ', '.sprintf(l10n('Rated %d times, score : %.2f'), $row['nb_rates'], $row['rating_score']);
+}
+
+$query = '
+SELECT *
+ FROM '.IMAGE_FORMAT_TABLE.'
+ WHERE image_id = '.$row['id'].'
+;';
+$formats = query2array($query);
+
+if (!empty($formats))
+{
+ $format_strings = array();
+
+ foreach ($formats as $format)
+ {
+ $format_strings[] = sprintf('%s (%.2fMB)', $format['ext'], $format['filesize']/1024);
+ }
+
+ $intro_vars['formats'] = l10n('Formats: %s', implode(', ', $format_strings));
+}
+
+$template->assign('INTRO', $intro_vars);
+
+
+if (in_array(get_extension($row['path']),$conf['picture_ext']))
+{
+ $template->assign('U_COI', get_root_url().'admin.php?page=picture_coi&image_id='.$_GET['image_id']);
+}
+
+// image level options
+$selected_level = isset($_POST['level']) ? $_POST['level'] : $row['level'];
+$template->assign(
+ array(
+ 'level_options'=> get_privacy_level_options(),
+ 'level_options_selected' => array($selected_level)
+ )
+ );
+
+// categories
+$query = '
+SELECT category_id, uppercats, dir
+ FROM '.IMAGE_CATEGORY_TABLE.' AS ic
+ INNER JOIN '.CATEGORIES_TABLE.' AS c
+ ON c.id = ic.category_id
+ WHERE image_id = '.$_GET['image_id'].'
+;';
+$result = pwg_query($query);
+
+$related_categories = array();
+$related_categories_ids = array();
+
+while ($row = pwg_db_fetch_assoc($result))
+{
+ $name =
+ get_cat_display_name_cache(
+ $row['uppercats'],
+ get_root_url().'admin.php?page=album-'
+ );
+
+ if ($row['category_id'] == $storage_category_id)
+ {
+ $template->assign('STORAGE_CATEGORY', $name);
+ }
+
+ $related_categories[$row['category_id']] = array('name' => $name, 'unlinkable' => $row['category_id'] != $storage_category_id);
+ $related_categories_ids[] = $row['category_id'];
+}
+
+$template->assign('related_categories', $related_categories);
+$template->assign('related_categories_ids', $related_categories_ids);
+
+// jump to link
+//
+// 1. if an edit_context is available, we use it (without checking permissions)
+// 2. else if user level is higher than image level, randomly find an authorized category
+// 3. else no jumpto link
+
+if ($custom_context = get_edit_context($_GET['image_id']))
+{
+ $template->assign('U_JUMPTO', make_picture_url(array('image_id' => $_GET['image_id'])).'/'.$custom_context);
+}
+elseif ($user['level'] >= $page['image']['level'])
+{
+ $query = '
+SELECT category_id
+ FROM '.IMAGE_CATEGORY_TABLE.'
+ WHERE image_id = '.$_GET['image_id'].'
+;';
+
+ $authorizeds = array_diff(
+ array_from_query($query, 'category_id'),
+ explode(
+ ',',
+ calculate_permissions($user['id'], $user['status'])
+ )
+ );
+
+ if (count($authorizeds) > 0)
+ {
+ $category = $authorizeds[array_rand($authorizeds)];
+
+ $url_img = make_picture_url(
+ array(
+ 'image_id' => $_GET['image_id'],
+ 'image_file' => $image_file,
+ 'category' => $cache['cat_names'][ $category ],
+ )
+ );
+
+ $template->assign('U_JUMPTO', $url_img);
+ }
+}
+
+// associate to albums
+$query = '
+SELECT id
+ FROM '.CATEGORIES_TABLE.'
+ INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON id = category_id
+ WHERE image_id = '.$_GET['image_id'].'
+;';
+$associated_albums = query2array($query, null, 'id');
+
+$template->assign(array(
+ 'associated_albums' => $associated_albums,
+ 'represented_albums' => $represented_albums,
+ 'STORAGE_ALBUM' => $storage_category_id,
+ 'CACHE_KEYS' => get_admin_client_cache_keys(array('tags', 'categories')),
+ 'PWG_TOKEN' => get_pwg_token(),
+ ));
+
+trigger_notify('loc_end_picture_modify');
+
+//----------------------------------------------------------- sending html code
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'picture_modify');
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/plugin.php b/Piwingo/piwigo-data/piwigo/admin/plugin.php
new file mode 100644
index 0000000..7738d6f
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/plugin.php
@@ -0,0 +1,59 @@
+
diff --git a/Piwingo/piwigo-data/piwigo/admin/plugins.php b/Piwingo/piwigo-data/piwigo/admin/plugins.php
new file mode 100644
index 0000000..41517b9
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/plugins.php
@@ -0,0 +1,36 @@
+set_id('plugins');
+$tabsheet->select($page['tab']);
+$tabsheet->assign();
+
+if ($page['tab'] == 'update') {
+ include(PHPWG_ROOT_PATH.'admin/updates_ext.php');
+ $template->assign('ADMIN_PAGE_TITLE', l10n('Plugins'));
+}
+else
+{
+ include(PHPWG_ROOT_PATH.'admin/plugins_'.$page['tab'].'.php');
+}
+?>
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/plugins_installed.php b/Piwingo/piwigo-data/piwigo/admin/plugins_installed.php
new file mode 100644
index 0000000..d5c7cf2
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/plugins_installed.php
@@ -0,0 +1,219 @@
+set_filenames(array('plugins' => 'plugins_installed.tpl'));
+
+// should we display details on plugins?
+if (isset($_GET['show_details']))
+{
+ if (1 == $_GET['show_details'])
+ {
+ $show_details = true;
+ }
+ else
+ {
+ $show_details = false;
+ }
+
+ pwg_set_session_var('plugins_show_details', $show_details);
+}
+elseif (null != pwg_get_session_var('plugins_show_details'))
+{
+ $show_details = pwg_get_session_var('plugins_show_details');
+}
+else
+{
+ $show_details = false;
+}
+
+$base_url = get_root_url().'admin.php?page='.$page['page'];
+$pwg_token = get_pwg_token();
+$action_url = $base_url.'&plugin='.'%s'.'&pwg_token='.$pwg_token;
+
+$plugins = new plugins();
+
+//--------------------------------------------------------Incompatible Plugins
+if (isset($_GET['incompatible_plugins']))
+{
+ $incompatible_plugins_raw = $plugins->get_incompatible_plugins();
+
+ if (false === $incompatible_plugins_raw)
+ {
+ echo json_encode(array());
+ exit;
+ }
+
+ $incompatible_plugins = array();
+
+ foreach ($incompatible_plugins_raw as $plugin => $version)
+ {
+ if ($plugin == '~~expire~~') continue;
+ $incompatible_plugins[] = $plugin;
+
+ }
+ echo json_encode($incompatible_plugins);
+ exit;
+}
+
+//--------------------------------------------------------Get the menu with the depreciated version
+
+$plugin_menu_links_deprec = trigger_change('get_admin_plugin_menu_links', array());
+
+$settings_url_for_plugin_deprec = array();
+
+foreach ($plugin_menu_links_deprec as $value)
+{
+ if (preg_match('/^admin\.php\?page=plugin-(.*)$/', $value["URL"], $matches)) {
+ $settings_url_for_plugin_deprec[$matches[1]] = $value["URL"];
+ } elseif (preg_match('/^.*section=(.*?)[\/&%].*$/', $value["URL"], $matches)) {
+ $settings_url_for_plugin_deprec[$matches[1]] = $value["URL"];
+ }
+}
+
+// +-----------------------------------------------------------------------+
+// | start template output |
+// +-----------------------------------------------------------------------+
+
+$plugins->sort_fs_plugins('name');
+$merged_extensions = $plugins->get_merged_extensions();
+$merged_plugins = false;
+$tpl_plugins = array();
+$count_types_plugins = array("active"=>0, "inactive"=>0, "missing"=>0, "merged"=>0);
+
+foreach($plugins->fs_plugins as $plugin_id => $fs_plugin)
+{
+ if (isset($_SESSION['incompatible_plugins'][$plugin_id])
+ and $fs_plugin['version'] != $_SESSION['incompatible_plugins'][$plugin_id])
+ {
+ // Incompatible plugins must be reinitilized
+ unset($_SESSION['incompatible_plugins']);
+ }
+
+ $setting_url = '';
+ if (isset($settings_url_for_plugin_deprec[$plugin_id])) { //old version
+ $setting_url = $settings_url_for_plugin_deprec[$plugin_id];
+ } else if ($fs_plugin['hasSettings']) { // new version
+ $setting_url = "admin.php?page=plugin-".$plugin_id;
+
+ if (preg_match('/^piwigo-(videojs|openstreetmap)$/', $plugin_id))
+ {
+ $setting_url = str_replace('piwigo-', 'piwigo_', $setting_url);
+ }
+ }
+
+ $url_to_replace = array(
+ 'http://piwigo.org/ext',
+ 'https://piwigo.org/ext'
+ );
+ $visit_url = str_replace($url_to_replace, PEM_URL, $fs_plugin['uri']);
+
+ $tpl_plugin = array(
+ 'ID' => $plugin_id,
+ 'NAME' => $fs_plugin['name'],
+ 'VISIT_URL' => $visit_url,
+ 'VERSION' => $fs_plugin['version'],
+ 'DESC' => $fs_plugin['description'],
+ 'AUTHOR' => $fs_plugin['author'],
+ 'AUTHOR_URL' => @$fs_plugin['author uri'],
+ 'U_ACTION' => sprintf($action_url, $plugin_id),
+ 'SETTINGS_URL' => $setting_url,
+ );
+
+ if (isset($plugins->db_plugins_by_id[$plugin_id]))
+ {
+ $tpl_plugin['STATE'] = $plugins->db_plugins_by_id[$plugin_id]['state'];
+ }
+ else
+ {
+ $tpl_plugin['STATE'] = 'inactive';
+ }
+
+ if (isset($fs_plugin['extension']) and isset($merged_extensions[$fs_plugin['extension']]))
+ {
+ // Deactivate manually plugin from database
+ $query = 'UPDATE '.PLUGINS_TABLE.' SET state=\'inactive\' WHERE id=\''.$plugin_id.'\'';
+ pwg_query($query);
+
+ $tpl_plugin['STATE'] = 'merged';
+ $tpl_plugin['DESC'] = l10n('THIS PLUGIN IS NOW PART OF PIWIGO CORE! DELETE IT NOW.');
+ $merged_plugins = true;
+ }
+
+ $count_types_plugins[$tpl_plugin['STATE']]++;
+
+ $tpl_plugins[] = $tpl_plugin;
+}
+
+$template->append('plugin_states', 'active');
+$template->append('plugin_states', 'inactive');
+
+if ($merged_plugins)
+{
+ $template->append('plugin_states', 'merged');
+}
+
+$missing_plugin_ids = array_diff(
+ array_keys($plugins->db_plugins_by_id),
+ array_keys($plugins->fs_plugins)
+ );
+
+if (count($missing_plugin_ids) > 0)
+{
+ foreach ($missing_plugin_ids as $plugin_id)
+ {
+ $tpl_plugins[] = array(
+ 'NAME' => $plugin_id,
+ 'ID' => $plugin_id,
+ 'VERSION' => $plugins->db_plugins_by_id[$plugin_id]['version'],
+ 'DESC' => l10n('ERROR: THIS PLUGIN IS MISSING BUT IT IS INSTALLED! UNINSTALL IT NOW.'),
+ 'U_ACTION' => sprintf($action_url, $plugin_id),
+ 'STATE' => 'missing',
+ );
+ $count_types_plugins['missing']++;
+ }
+ $template->append('plugin_states', 'missing');
+}
+
+// sort plugins by state then by name
+function cmp($a, $b)
+{
+ $s = array('merged' => 0, 'missing' => 1, 'active' => 2, 'inactive' => 3);
+
+ if($a['STATE'] == $b['STATE'])
+ return strcasecmp($a['NAME'], $b['NAME']);
+ else
+ return $s[$a['STATE']] >= $s[$b['STATE']];
+}
+
+// Stoped plugin sorting for new plugin manager
+// usort($tpl_plugins, 'cmp');
+
+$template->assign(
+ array(
+ 'plugins' => $tpl_plugins,
+ 'count_types_plugins' => $count_types_plugins,
+ 'PWG_TOKEN' => $pwg_token,
+ 'base_url' => $base_url,
+ 'show_details' => $show_details,
+ 'max_inactive_before_hide' => isset($_GET['show_inactive']) ? 999 : 8,
+ 'isWebmaster' => (is_webmaster()) ? 1 : 0,
+ 'ADMIN_PAGE_TITLE' => l10n('Plugins'),
+ 'view_selector' => userprefs_get_param('plugin-manager-view', 'classic'),
+ 'CONF_ENABLE_EXTENSIONS_INSTALL' => $conf['enable_extensions_install'],
+ )
+ );
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'plugins');
+?>
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/plugins_new.php b/Piwingo/piwigo-data/piwigo/admin/plugins_new.php
new file mode 100644
index 0000000..811b0e6
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/plugins_new.php
@@ -0,0 +1,208 @@
+set_filenames(array('plugins' => 'plugins_new.tpl'));
+
+$base_url = get_root_url().'admin.php?page='.$page['page'].'&tab='.$page['tab'];
+
+$plugins = new plugins();
+
+//------------------------------------------------------automatic installation
+if (isset($_GET['revision']) and isset($_GET['extension']))
+{
+ if (!is_webmaster())
+ {
+ $page['errors'][] = l10n('Webmaster status is required.');
+ }
+ else
+ {
+ check_pwg_token();
+
+ $install_status = $plugins->extract_plugin_files('install', $_GET['revision'], $_GET['extension'], $plugin_id);
+
+ redirect($base_url.'&installstatus='.$install_status.'&plugin_id='.$plugin_id);
+ }
+}
+
+//--------------------------------------------------------------install result
+if (isset($_GET['installstatus']))
+{
+ switch ($_GET['installstatus'])
+ {
+ case 'ok':
+ // since Piwigo 12, you need to be on the page of installed plugins to active a plugin with
+ // a JS action, no need to provide plugin_id in URL, just link to the page of installed
+ // plugins, filtered on deactivated plugins. The webmaster will have to find its newly
+ // installed plugin and click on the activation switch.
+ $activate_url = get_root_url().'admin.php?page=plugins&filter=deactivated';
+
+ $page['infos'][] = l10n('Plugin has been successfully copied');
+ $page['infos'][] = '' . l10n('Activate it now') . '';
+
+ if (isset($plugins->fs_plugins[$_GET['plugin_id']]))
+ {
+ pwg_activity(
+ 'system',
+ ACTIVITY_SYSTEM_PLUGIN,
+ 'install',
+ array(
+ 'plugin_id' => $_GET['plugin_id'],
+ 'version' => $plugins->fs_plugins[$_GET['plugin_id']]['version'],
+ )
+ );
+ }
+ break;
+
+ case 'temp_path_error':
+ $page['errors'][] = l10n('Can\'t create temporary file.');
+ break;
+
+ case 'dl_archive_error':
+ $page['errors'][] = l10n('Can\'t download archive.');
+ break;
+
+ case 'archive_error':
+ $page['errors'][] = l10n('Can\'t read or extract archive.');
+ break;
+
+ default:
+ $page['errors'][] = l10n('An error occured during extraction (%s).', htmlspecialchars($_GET['installstatus']));
+ $page['errors'][] = l10n('Please check "plugins" folder and sub-folders permissions (CHMOD).');
+ }
+}
+
+//---------------------------------------------------------------Order options
+$template->assign('order_options',
+ array(
+ 'date' => l10n('Post date'),
+ 'revision' => l10n('Last revisions'),
+ 'name' => l10n('Name'),
+ 'author' => l10n('Author'),
+ 'downloads' => l10n('Number of downloads')));
+
+// +-----------------------------------------------------------------------+
+// | start template output |
+// +-----------------------------------------------------------------------+
+
+// Beta test : show plugins of last version on PEM if the current version isn't present
+// If the current version in known, give the current and last version's compatible plugins
+$beta_test = false;
+
+if(isset($_GET['beta-test']) && $_GET['beta-test'] == 'true')
+{
+ $beta_test = true;
+}
+
+if ($plugins->get_server_plugins(true, $beta_test))
+{
+ /* order plugins */
+ if (pwg_get_session_var('plugins_new_order') != null)
+ {
+ $order_selected = pwg_get_session_var('plugins_new_order');
+ $plugins->sort_server_plugins($order_selected);
+ $template->assign('order_selected', $order_selected);
+ }
+ else
+ {
+ $plugins->sort_server_plugins('date');
+ $template->assign('order_selected', 'date');
+ }
+
+ foreach($plugins->server_plugins as $plugin)
+ {
+ $ext_desc = trim($plugin['extension_description'], " \n\r");
+ list($small_desc) = explode("\n", wordwrap($ext_desc, 200));
+
+ $url_auto_install = htmlentities($base_url)
+ . '&revision=' . $plugin['revision_id']
+ . '&extension=' . $plugin['extension_id']
+ . '&pwg_token='.get_pwg_token()
+ ;
+
+ // get the age of the last revision in days
+ $last_revision_diff = date_diff(date_create($plugin['revision_date']), date_create());
+
+ $certification = 1;
+ $has_compatible_version = false;
+
+ // Check if the current version is in the compatible version (not necessary if we are in beta test)
+ if ($beta_test) {
+ foreach ($plugin['compatible_with_versions'] as $vers) {
+ if (get_branch_from_version($vers) == get_branch_from_version(PHPWG_VERSION))
+ {
+ $has_compatible_version = true;
+ }
+ }
+ } else {
+ $has_compatible_version = true;
+ }
+
+ if (!$has_compatible_version) {
+ $certification = -1;
+ }
+ elseif ($last_revision_diff->days < 90) // if the last revision is new of 3 month or less
+ {
+ $certification = 3;
+ }
+ elseif ($last_revision_diff->days < 180) // 6 month or less
+ {
+ $certification = 2;
+ }
+ elseif ($last_revision_diff->y > 3) // 3 years or less
+ {
+ $certification = 0;
+ }
+ // Between 6 month and 3 years : certification = 1
+
+ $template->append('plugins', array(
+ 'ID' => $plugin['extension_id'],
+ 'EXT_NAME' => $plugin['extension_name'],
+ 'EXT_URL' => PEM_URL.'/extension_view.php?eid='.$plugin['extension_id'],
+ 'SMALL_DESC' => trim($small_desc, " \r\n"),
+ 'BIG_DESC' => $ext_desc,
+ 'VERSION' => $plugin['revision_name'],
+ 'REVISION_DATE' => preg_replace('/[^0-9]/', '', strtotime($plugin['revision_date'])),
+ 'REVISION_FORMATED_DATE' => format_date($plugin['revision_date'], array('day','month','year')).", ".time_since($plugin['revision_date'], "day"),
+ 'AUTHOR' => $plugin['author_name'],
+ 'DOWNLOADS' => $plugin['extension_nb_downloads'],
+ 'URL_INSTALL' => $url_auto_install,
+ 'CERTIFICATION' => $certification,
+ 'RATING' => $plugin['rating_score'],
+ 'NB_RATINGS' => $plugin['nb_ratings'],
+ 'SCREENSHOT' => (key_exists('screenshot_url', $plugin)) ? $plugin['screenshot_url']:'',
+ 'TAGS' => $plugin["tags"],
+ ));
+ }
+
+
+}
+else
+{
+ $page['errors'][] = l10n('Can\'t connect to server.');
+}
+
+if (!$beta_test and preg_match('/(beta|RC)/', PHPWG_VERSION))
+{
+ $template->assign('BETA_URL', $base_url.'&beta-test=true');
+}
+$template->assign('ADMIN_PAGE_TITLE', l10n('Plugins'));
+$template->assign('BETA_TEST', $beta_test);
+$template->assign_var_from_handle('ADMIN_CONTENT', 'plugins');
+?>
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/popuphelp.php b/Piwingo/piwigo-data/piwigo/admin/popuphelp.php
new file mode 100644
index 0000000..c7d24b5
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/popuphelp.php
@@ -0,0 +1,94 @@
+'.$title.'';
+ $page['meta_robots']=array('noindex'=>1, 'nofollow'=>1);
+
+ // set required template variables to avoid "Undefined array key" with PHP 8
+ $template->assign(
+ array(
+ 'U_RETURN' => '',
+ 'USERNAME' => '',
+ 'U_FAQ'=> '',
+ 'U_CHANGE_THEME' => '',
+ 'U_LOGOUT' => '',
+ )
+ );
+
+ include(PHPWG_ROOT_PATH.'include/page_header.php');
+}
+
+if
+ (
+ isset($_GET['page'])
+ and preg_match('/^[a-z_]*$/', $_GET['page'])
+ )
+{
+ $help_content = load_language(
+ 'help/'.$_GET['page'].'.html',
+ '',
+ array(
+ 'force_fallback' => 'en_UK',
+ 'return' => true,
+ )
+ );
+
+ if ($help_content == false)
+ {
+ $help_content = '';
+ }
+
+ $help_content = trigger_change('get_popup_help_content', $help_content, $_GET['page']);
+}
+else
+{
+ die('Hacking attempt!');
+}
+
+$template->set_filename('popuphelp','popuphelp.tpl');
+
+$template->assign(
+ array
+ (
+ 'HELP_CONTENT' => $help_content
+ ));
+
+if (isset($_GET['output']) and 'content_only' == $_GET['output'])
+{
+ echo $help_content;
+ exit();
+}
+
+// +-----------------------------------------------------------------------+
+// | html code display |
+// +-----------------------------------------------------------------------+
+
+$template->pparse('popuphelp');
+
+include(PHPWG_ROOT_PATH.'include/page_tail.php');
+
+?>
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/profile.php b/Piwingo/piwigo-data/piwigo/admin/profile.php
new file mode 100644
index 0000000..8251408
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/profile.php
@@ -0,0 +1,34 @@
+set_filename('profile', 'profile.tpl');
+$template->assign_var_from_handle('ADMIN_CONTENT', 'profile');
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/rating.php b/Piwingo/piwigo-data/piwigo/admin/rating.php
new file mode 100644
index 0000000..c18e723
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/rating.php
@@ -0,0 +1,258 @@
+set_id('rating');
+$tabsheet->select('rating');
+$tabsheet->assign();
+
+// +-----------------------------------------------------------------------+
+// | initialization |
+// +-----------------------------------------------------------------------+
+if (isset($_GET['start']) and is_numeric($_GET['start']))
+{
+ $start = $_GET['start'];
+}
+else
+{
+ $start = 0;
+}
+
+$elements_per_page=10;
+if (isset($_GET['display']) and is_numeric($_GET['display']))
+{
+ $elements_per_page = $_GET['display'];
+}
+
+$order_by_index=0;
+if (isset($_GET['order_by']) and is_numeric($_GET['order_by']))
+{
+ $order_by_index = $_GET['order_by'];
+}
+
+$page['user_filter'] = '';
+if (isset($_GET['users']))
+{
+ if ($_GET['users'] == 'user')
+ {
+ $page['user_filter'] = ' AND r.user_id <> '.$conf['guest_id'];
+ }
+ elseif ($_GET['users'] == 'guest')
+ {
+ $page['user_filter'] = ' AND r.user_id = '.$conf['guest_id'];
+ }
+}
+
+$page['cat_filter'] = '';
+if (isset($_GET['cat']) and is_numeric($_GET['cat']))
+{
+ $cat_ids = get_subcat_ids(array($_GET['cat']));
+
+ if (count($cat_ids) > 0)
+ {
+ $page['cat_filter'] = ' AND ic.category_id IN ('.implode(',', $cat_ids).')';
+ }
+}
+
+$users = array();
+$query = '
+SELECT '.$conf['user_fields']['username'].' as username, '.$conf['user_fields']['id'].' as id
+ FROM '.USERS_TABLE.'
+;';
+$result = pwg_query($query);
+while ($row = pwg_db_fetch_assoc($result))
+{
+ $users[$row['id']]=stripslashes($row['username']);
+}
+
+
+$query = '
+SELECT
+ COUNT(DISTINCT(r.element_id))
+ FROM '.RATE_TABLE.' AS r';
+
+if (!empty($page['cat_filter']))
+{
+ $query.= '
+ JOIN '.IMAGES_TABLE.' AS i ON r.element_id = i.id
+ JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON ic.image_id = i.id';
+}
+
+$query.= '
+WHERE 1=1'. $page['user_filter'];
+list($nb_images) = pwg_db_fetch_row(pwg_query($query));
+
+$query = '
+SELECT
+ COUNT(*)
+ FROM '.RATE_TABLE.
+';';
+list($nb_elements) = pwg_db_fetch_row(pwg_query($query));
+
+// +-----------------------------------------------------------------------+
+// | template init |
+// +-----------------------------------------------------------------------+
+
+$template->set_filename('rating', 'rating.tpl');
+
+$template->assign(
+ array(
+ 'navbar' => create_navigation_bar(
+ PHPWG_ROOT_PATH.'admin.php'.get_query_string_diff(array('start','del')),
+ $nb_images,
+ $start,
+ $elements_per_page
+ ),
+ 'F_ACTION' => PHPWG_ROOT_PATH.'admin.php',
+ 'DISPLAY' => $elements_per_page,
+ 'NB_ELEMENTS' => $nb_elements,
+ 'category' => (isset($_GET['cat']) ? array($_GET['cat']) : array()),
+ 'CACHE_KEYS' => get_admin_client_cache_keys(array('categories')),
+ )
+ );
+
+
+
+$available_order_by= array(
+ array(l10n('Rate date'), 'recently_rated DESC'),
+ array(l10n('Rating score'), 'score DESC'),
+ array(l10n('Average rate'), 'avg_rates DESC'),
+ array(l10n('Number of rates'), 'nb_rates DESC'),
+ array(l10n('Sum of rates'), 'sum_rates DESC'),
+ array(l10n('File name'), 'file DESC'),
+ array(l10n('Creation date'), 'date_creation DESC'),
+ array(l10n('Post date'), 'date_available DESC'),
+ );
+
+for ($i=0; $iappend(
+ 'order_by_options',
+ $available_order_by[$i][0]
+ );
+}
+$template->assign('order_by_options_selected', array($order_by_index) );
+
+
+$user_options = array(
+ 'all' => l10n('all'),
+ 'user' => l10n('Users'),
+ 'guest' => l10n('Guests'),
+ );
+
+$template->assign('user_options', $user_options );
+$template->assign('user_options_selected', array(@$_GET['users']) );
+$template->assign('ADMIN_PAGE_TITLE', l10n('Rating'));
+
+$query = '
+SELECT i.id,
+ i.path,
+ i.file,
+ i.representative_ext,
+ i.rating_score AS score,
+ MAX(r.date) AS recently_rated,
+ ROUND(AVG(r.rate),2) AS avg_rates,
+ COUNT(r.rate) AS nb_rates,
+ SUM(r.rate) AS sum_rates
+ FROM '.RATE_TABLE.' AS r
+ LEFT JOIN '.IMAGES_TABLE.' AS i ON r.element_id = i.id';
+
+if (!empty($page['cat_filter']))
+{
+ $query.= '
+ JOIN '.IMAGE_CATEGORY_TABLE.' AS ic ON ic.image_id = i.id';
+}
+
+$query.= '
+ WHERE 1 = 1 ' . $page['user_filter'] . $page['cat_filter'] . '
+ GROUP BY i.id,
+ i.path,
+ i.file,
+ i.representative_ext,
+ i.rating_score,
+ r.element_id
+ ORDER BY ' . $available_order_by[$order_by_index][1] .'
+ LIMIT '.$elements_per_page.' OFFSET '.$start.'
+;';
+
+$images = array();
+$result = pwg_query($query);
+while ($row = pwg_db_fetch_assoc($result))
+{
+ $images[] = $row;
+}
+
+$template->assign( 'images', array() );
+foreach ($images as $image)
+{
+ $thumbnail_src = DerivativeImage::thumb_url($image);
+
+ $image_url = get_root_url().'admin.php?page=photo-'.$image['id'];
+
+ $query = 'SELECT *
+FROM '.RATE_TABLE.' AS r
+WHERE r.element_id='.$image['id'] . '
+ORDER BY date DESC;';
+ $result = pwg_query($query);
+ $nb_rates = pwg_db_num_rows($result);
+
+ $tpl_image =
+ array(
+ 'id' => $image['id'],
+ 'U_THUMB' => $thumbnail_src,
+ 'U_URL' => $image_url,
+ 'SCORE_RATE' => $image['score'],
+ 'AVG_RATE' => $image['avg_rates'],
+ 'SUM_RATE' => $image['sum_rates'],
+ 'NB_RATES' => (int)$image['nb_rates'],
+ 'NB_RATES_TOTAL' => (int)$nb_rates,
+ 'FILE' => $image['file'],
+ 'rates' => array()
+ );
+
+ while ($row = pwg_db_fetch_assoc($result))
+ {
+ if ( isset($users[$row['user_id']]) )
+ {
+ $user_rate = $users[$row['user_id']];
+ }
+ else
+ {
+ $user_rate = '? '. $row['user_id'];
+ }
+ if ( strlen($row['anonymous_id'])>0 )
+ {
+ $user_rate .= '('.$row['anonymous_id'].')';
+ }
+
+ $row['USER'] = $user_rate;
+ $tpl_image['rates'][] = $row;
+ }
+ $template->append( 'images', $tpl_image );
+}
+
+// +-----------------------------------------------------------------------+
+// | sending html code |
+// +-----------------------------------------------------------------------+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'rating');
+?>
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/rating_user.php b/Piwingo/piwigo-data/piwigo/admin/rating_user.php
new file mode 100644
index 0000000..f58427e
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/rating_user.php
@@ -0,0 +1,253 @@
+set_id('rating');
+$tabsheet->select('rating_user');
+$tabsheet->assign();
+
+$filter_min_rates = 2;
+if (isset($_GET['f_min_rates']))
+{
+ $filter_min_rates = (int)$_GET['f_min_rates'];
+}
+
+$consensus_top_number = $conf['top_number'];
+if (isset($_GET['consensus_top_number']))
+{
+ $consensus_top_number = (int)$_GET['consensus_top_number'];
+}
+
+// build users
+global $conf;
+$query = 'SELECT DISTINCT
+ u.'.$conf['user_fields']['id'].' AS id,
+ u.'.$conf['user_fields']['username'].' AS name,
+ ui.status
+ FROM '.USERS_TABLE.' AS u INNER JOIN '.USER_INFOS_TABLE.' AS ui
+ ON u.'.$conf['user_fields']['id'].' = ui.user_id';
+
+$users_by_id = array();
+$result = pwg_query($query);
+while ($row = pwg_db_fetch_assoc($result))
+{
+ $users_by_id[(int)$row['id']] = array(
+ 'name' => $row['name'],
+ 'anon' => is_autorize_status(ACCESS_CLASSIC, $row['status']) ? false : true
+ );
+}
+
+$by_user_rating_model = array( 'rates' => array() );
+foreach($conf['rate_items'] as $rate)
+{
+ $by_user_rating_model['rates'][$rate] = array();
+}
+
+// by user aggregation
+$image_ids = array();
+$by_user_ratings = array();
+$query = '
+SELECT * FROM '.RATE_TABLE.' ORDER by date DESC';
+$result = pwg_query($query);
+while ($row = pwg_db_fetch_assoc($result))
+{
+ if (!isset($users_by_id[$row['user_id']]))
+ {
+ $users_by_id[$row['user_id']] = array('name' => '???'.$row['user_id'], 'anon' => false);
+ }
+ $usr = $users_by_id[$row['user_id']];
+ if ($usr['anon'])
+ {
+ $user_key = $usr['name'].'('.$row['anonymous_id'].')';
+ }
+ else
+ {
+ $user_key = $usr['name'];
+ }
+ $rating = & $by_user_ratings[$user_key];
+ if ( is_null($rating) )
+ {
+ $rating = $by_user_rating_model;
+ $rating['uid'] = (int)$row['user_id'];
+ $rating['aid'] = $usr['anon'] ? $row['anonymous_id'] : '';
+ $rating['last_date'] = $rating['first_date'] = $row['date'];
+ }
+ else
+ $rating['first_date'] = $row['date'];
+
+ $rating['rates'][$row['rate']][] = array(
+ 'id' => $row['element_id'],
+ 'date' => $row['date'],
+ );
+ $image_ids[$row['element_id']] = 1;
+ unset($rating);
+}
+
+// get image tn urls
+$image_urls = array();
+if (count($image_ids) > 0 )
+{
+ $query = 'SELECT id, name, file, path, representative_ext, level
+ FROM '.IMAGES_TABLE.'
+ WHERE id IN ('.implode(',', array_keys($image_ids)).')';
+ $result = pwg_query($query);
+ $params = ImageStdParams::get_by_type(IMG_SQUARE);
+ while ($row = pwg_db_fetch_assoc($result))
+ {
+ $image_urls[ $row['id'] ] = array(
+ 'tn' => DerivativeImage::url($params, $row),
+ 'page' => make_picture_url( array('image_id'=>$row['id'], 'image_file'=>$row['file']) ),
+ );
+ }
+}
+
+//all image averages
+$query='SELECT element_id,
+ AVG(rate) AS avg
+ FROM '.RATE_TABLE.'
+ GROUP BY element_id';
+$all_img_sum = array();
+$result = pwg_query($query);
+while ($row = pwg_db_fetch_assoc($result))
+{
+ $all_img_sum[(int)$row['element_id']] = array( 'avg'=>(float)$row['avg'] );
+}
+
+$query='SELECT id
+ FROM '.IMAGES_TABLE.'
+ ORDER by rating_score DESC
+ LIMIT '.$consensus_top_number;
+$best_rated = array_flip( array_from_query($query, 'id'));
+
+// by user stats
+foreach($by_user_ratings as $id => &$rating)
+{
+ $c=0; $s=0; $ss=0; $consensus_dev=0; $consensus_dev_top=0; $consensus_dev_top_count=0;
+ foreach($rating['rates'] as $rate => $rates)
+ {
+ $ct = count($rates);
+ $c += $ct;
+ $s += $ct * $rate;
+ $ss += $ct * $rate * $rate;
+ foreach($rates as $id_date)
+ {
+ $dev = abs($rate - $all_img_sum[$id_date['id']]['avg']);
+ $consensus_dev += $dev;
+ if (isset($best_rated[$id_date['id']]))
+ {
+ $consensus_dev_top += $dev;
+ $consensus_dev_top_count++;
+ }
+ }
+ }
+
+ $consensus_dev /= $c;
+ if ($consensus_dev_top_count)
+ $consensus_dev_top /= $consensus_dev_top_count;
+
+ $var = ($ss - $s*$s/$c)/$c;
+ $rating += array(
+ 'id' => $id,
+ 'count' => $c,
+ 'avg' => $s/$c,
+ 'cv' => $s==0 ? -1 : sqrt($var)/($s/$c), // http://en.wikipedia.org/wiki/Coefficient_of_variation
+ 'cd' => $consensus_dev,
+ 'cdtop' => $consensus_dev_top_count ? $consensus_dev_top : '',
+ );
+}
+unset($rating);
+
+// filter
+foreach($by_user_ratings as $id => $rating)
+{
+ if ($rating['count'] <= $filter_min_rates)
+ {
+ unset($by_user_ratings[$id]);
+ }
+}
+
+
+function avg_compare($a, $b)
+{
+ $d = $a['avg'] - $b['avg'];
+ return ($d==0) ? 0 : ($d<0 ? -1 : 1);
+}
+
+function count_compare($a, $b)
+{
+ $d = $a['count'] - $b['count'];
+ return ($d==0) ? 0 : ($d<0 ? -1 : 1);
+}
+
+function cv_compare($a, $b)
+{
+ $d = $b['cv'] - $a['cv']; //desc
+ return ($d==0) ? 0 : ($d<0 ? -1 : 1);
+}
+
+function consensus_dev_compare($a, $b)
+{
+ $d = $b['cd'] - $a['cd']; //desc
+ return ($d==0) ? 0 : ($d<0 ? -1 : 1);
+}
+
+function last_rate_compare($a, $b)
+{
+ return -strcmp( $a['last_date'], $b['last_date']);
+}
+
+$order_by_index=4;
+if (isset($_GET['order_by']) and is_numeric($_GET['order_by']))
+{
+ $order_by_index = $_GET['order_by'];
+}
+
+$available_order_by= array(
+ array(l10n('Average rate'), 'avg_compare'),
+ array(l10n('Number of rates'), 'count_compare'),
+ array(l10n('Variation'), 'cv_compare'),
+ array(l10n('Consensus deviation'), 'consensus_dev_compare'),
+ array(l10n('Last'), 'last_rate_compare'),
+ );
+
+for ($i=0; $iappend(
+ 'order_by_options',
+ $available_order_by[$i][0]
+ );
+}
+$template->assign('order_by_options_selected', array($order_by_index) );
+
+$x = uasort($by_user_ratings, $available_order_by[$order_by_index][1] );
+
+$query = '
+SELECT
+ COUNT(*)
+ FROM '.RATE_TABLE.
+';';
+list($nb_elements) = pwg_db_fetch_row(pwg_query($query));
+
+$template->assign( array(
+ 'F_ACTION' => get_root_url().'admin.php',
+ 'F_MIN_RATES' => $filter_min_rates,
+ 'CONSENSUS_TOP_NUMBER' => $consensus_top_number,
+ 'available_rates' => $conf['rate_items'],
+ 'ratings' => $by_user_ratings,
+ 'image_urls' => $image_urls,
+ 'TN_WIDTH' => ImageStdParams::get_by_type(IMG_SQUARE)->sizing->ideal_size[0],
+ 'NB_ELEMENTS' => $nb_elements,
+ 'ADMIN_PAGE_TITLE' => l10n('Rating'),
+ ));
+$template->set_filename('rating', 'rating_user.tpl');
+$template->assign_var_from_handle('ADMIN_CONTENT', 'rating');
+
+?>
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/site_manager.php b/Piwingo/piwigo-data/piwigo/admin/site_manager.php
new file mode 100644
index 0000000..1e3f924
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/site_manager.php
@@ -0,0 +1,185 @@
+set_filenames(array('site_manager'=>'site_manager.tpl'));
+
+// +-----------------------------------------------------------------------+
+// | tabs |
+// +-----------------------------------------------------------------------+
+
+include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
+$my_base_url = get_root_url().'admin.php?page=';
+
+$tabsheet = new tabsheet();
+$tabsheet->set_id('site_update');
+$tabsheet->select('site_maager');
+$tabsheet->assign();
+
+// +-----------------------------------------------------------------------+
+// | new site creation form |
+// +-----------------------------------------------------------------------+
+if (isset($_POST['submit']) and !empty($_POST['galleries_url']))
+{
+ $is_remote = url_is_remote( $_POST['galleries_url'] );
+ if ($is_remote)
+ {
+ fatal_error('remote sites not supported');
+ }
+ $url = preg_replace('/[\/]*$/', '', $_POST['galleries_url']);
+ $url.= '/';
+ if ( ! (strpos($url, '.') === 0 ) )
+ {
+ $url = './' . $url;
+ }
+
+ // site must not exists
+ $query = '
+SELECT COUNT(id) AS count
+ FROM '.SITES_TABLE.'
+ WHERE galleries_url = \''.$url.'\'
+;';
+ $row = pwg_db_fetch_assoc(pwg_query($query));
+ if ($row['count'] > 0)
+ {
+ $page['errors'][] = l10n('This site already exists').' ['.$url.']';
+ }
+ if (count($page['errors']) == 0)
+ {
+ if ( ! file_exists($url) )
+ {
+ $page['errors'][] = l10n('Directory does not exist').' ['.$url.']';
+ }
+ }
+
+ if (count($page['errors']) == 0)
+ {
+ $query = '
+INSERT INTO '.SITES_TABLE.'
+ (galleries_url)
+ VALUES
+ (\''.$url.'\')
+;';
+ pwg_query($query);
+ $page['infos'][] = $url.' '.l10n('created');
+ }
+}
+
+// +-----------------------------------------------------------------------+
+// | actions on site |
+// +-----------------------------------------------------------------------+
+if (isset($_GET['site']) and is_numeric($_GET['site']))
+{
+ $page['site'] = $_GET['site'];
+}
+if (isset($_GET['action']) and isset($page['site']))
+{
+ $query = '
+SELECT galleries_url
+ FROM '.SITES_TABLE.'
+ WHERE id = '.$page['site'].'
+;';
+ list($galleries_url) = pwg_db_fetch_row(pwg_query($query));
+ switch($_GET['action'])
+ {
+ case 'delete' :
+ {
+ delete_site($page['site']);
+ $page['infos'][] = $galleries_url.' '.l10n('deleted');
+ break;
+ }
+ }
+}
+
+$template->assign(
+ array(
+ 'F_ACTION' => get_root_url().'admin.php'.get_query_string_diff(array('action','site','pwg_token')),
+ 'PWG_TOKEN' => get_pwg_token(),
+ 'ADMIN_PAGE_TITLE' => l10n('Synchronize'),
+ )
+ );
+
+$query = '
+SELECT c.site_id, COUNT(DISTINCT c.id) AS nb_categories, COUNT(i.id) AS nb_images
+ FROM '.CATEGORIES_TABLE.' AS c LEFT JOIN '.IMAGES_TABLE.' AS i
+ ON c.id=i.storage_category_id
+ WHERE c.site_id IS NOT NULL
+ GROUP BY c.site_id
+;';
+$sites_detail = hash_from_query($query, 'site_id');
+
+$query = '
+SELECT *
+ FROM '.SITES_TABLE.'
+;';
+$result = pwg_query($query);
+
+while ($row = pwg_db_fetch_assoc($result))
+{
+ $is_remote = url_is_remote($row['galleries_url']);
+ $base_url = PHPWG_ROOT_PATH.'admin.php';
+ $base_url.= '?page=site_manager';
+ $base_url.= '&site='.$row['id'];
+ $base_url.= '&pwg_token='.get_pwg_token();
+ $base_url.= '&action=';
+
+ $update_url = PHPWG_ROOT_PATH.'admin.php';
+ $update_url.= '?page=site_update';
+ $update_url.= '&site='.$row['id'];
+
+ $tpl_var =
+ array(
+ 'NAME' => $row['galleries_url'],
+ 'TYPE' => l10n( $is_remote ? 'Remote' : 'Local' ),
+ 'CATEGORIES' => (int)@$sites_detail[$row['id']]['nb_categories'],
+ 'IMAGES' => (int)@$sites_detail[$row['id']]['nb_images'],
+ 'U_SYNCHRONIZE' => $update_url
+ );
+
+ if ($row['id'] != 1)
+ {
+ $tpl_var['U_DELETE'] = $base_url.'delete';
+ }
+
+ $plugin_links = array();
+ //$plugin_links is array of array composed of U_HREF, U_HINT & U_CAPTION
+ $plugin_links =
+ trigger_change('get_admins_site_links',
+ $plugin_links, $row['id'], $is_remote);
+ $tpl_var['plugin_links'] = $plugin_links;
+
+ $template->append('sites', $tpl_var);
+}
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'site_manager');
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/site_reader_local.php b/Piwingo/piwigo-data/piwigo/admin/site_reader_local.php
new file mode 100644
index 0000000..397159d
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/site_reader_local.php
@@ -0,0 +1,197 @@
+site_url = $url;
+ global $conf;
+ if (!isset($conf['flip_file_ext']))
+ {
+ $conf['flip_file_ext'] = array_flip($conf['file_ext']);
+ }
+ if (!isset($conf['flip_picture_ext']))
+ {
+ $conf['flip_picture_ext'] = array_flip($conf['picture_ext']);
+ }
+}
+
+/**
+ * Is this local site ok ?
+ *
+ * @return true on success, false otherwise
+ */
+function open()
+{
+ global $errors;
+
+ if (!is_dir($this->site_url))
+ {
+ $errors[] = array(
+ 'path' => $this->site_url,
+ 'type' => 'PWG-ERROR-NO-FS'
+ );
+
+ return false;
+ }
+
+ return true;
+}
+
+// retrieve file system sub-directories fulldirs
+function get_full_directories($basedir)
+{
+ $fs_fulldirs = get_fs_directories($basedir);
+ return $fs_fulldirs;
+}
+
+/**
+ * Returns an array with all file system files according to $conf['file_ext']
+ * and $conf['picture_ext']
+ * @param string $path recurse in this directory
+ * @return array like "pic.jpg"=>array('representative_ext'=>'jpg' ... )
+ */
+function get_elements($path)
+{
+ global $conf;
+
+ $subdirs = array();
+ $fs = array();
+ if (is_dir($path) && $contents = opendir($path) )
+ {
+ while (($node = readdir($contents)) !== false)
+ {
+ if ($node == '.' or $node == '..') continue;
+
+ if (is_file($path.'/'.$node))
+ {
+ $extension = strtolower(get_extension($node));
+ $filename_wo_ext = get_filename_wo_extension($node);
+
+ if ( isset($conf['flip_file_ext'][$extension]) )
+ {
+ $representative_ext = null;
+ if (! isset($conf['flip_picture_ext'][$extension]) )
+ {
+ $representative_ext = $this->get_representative_ext($path, $filename_wo_ext);
+ }
+
+ $fs[ $path.'/'.$node ] = array('representative_ext' => $representative_ext);
+
+ if ($conf['enable_formats'])
+ {
+ $fs[ $path.'/'.$node ]['formats'] = $this->get_formats($path, $filename_wo_ext);
+ }
+ }
+ }
+ else if (is_dir($path.'/'.$node)
+ and $node != 'pwg_high'
+ and $node != 'pwg_representative'
+ and $node != 'pwg_format'
+ and $node != 'thumbnail' )
+ {
+ $subdirs[] = $node;
+ }
+ } //end while readdir
+ closedir($contents);
+
+ foreach ($subdirs as $subdir)
+ {
+ $tmp_fs = $this->get_elements($path.'/'.$subdir);
+ $fs = array_merge($fs, $tmp_fs);
+ }
+ ksort($fs);
+ } //end if is_dir
+ return $fs;
+}
+
+// returns the name of the attributes that are supported for
+// files update/synchronization
+function get_update_attributes()
+{
+ return array('representative_ext');
+}
+
+function get_element_update_attributes($file)
+{
+ global $conf;
+ $data = array();
+
+ $filename = basename($file);
+ $extension = get_extension($filename);
+
+ $representative_ext = null;
+ if (! isset($conf['flip_picture_ext'][$extension]) )
+ {
+ $dirname = dirname($file);
+ $filename_wo_ext = get_filename_wo_extension($filename);
+ $representative_ext = $this->get_representative_ext($dirname, $filename_wo_ext);
+ }
+
+ $data['representative_ext'] = $representative_ext;
+ return $data;
+}
+
+// returns the name of the attributes that are supported for
+// metadata update/synchronization according to configuration
+function get_metadata_attributes()
+{
+ return get_sync_metadata_attributes();
+}
+
+// returns a hash of attributes (metadata+filesize+width,...) for file
+function get_element_metadata($infos)
+{
+ return get_sync_metadata($infos);
+}
+
+
+//-------------------------------------------------- private functions --------
+function get_representative_ext($path, $filename_wo_ext)
+{
+ global $conf;
+ $base_test = $path.'/pwg_representative/'.$filename_wo_ext.'.';
+ foreach ($conf['picture_ext'] as $ext)
+ {
+ $test = $base_test.$ext;
+ if (is_file($test))
+ {
+ return $ext;
+ }
+ }
+ return null;
+}
+
+function get_formats($path, $filename_wo_ext)
+{
+ global $conf;
+
+ $formats = array();
+
+ $base_test = $path.'/pwg_format/'.$filename_wo_ext.'.';
+
+ foreach ($conf['format_ext'] as $ext)
+ {
+ $test = $base_test.$ext;
+
+ if (is_file($test))
+ {
+ $formats[$ext] = floor(filesize($test) / 1024);
+ }
+ }
+
+ return $formats;
+}
+
+}
+?>
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/site_update.php b/Piwingo/piwigo-data/piwigo/admin/site_update.php
new file mode 100644
index 0000000..0478ad2
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/site_update.php
@@ -0,0 +1,1073 @@
+ array(
+ l10n('wrong filename'),
+ l10n('The name of directories and files must be composed of letters, numbers, "-", "_" or "."')
+ ),
+ 'PWG-ERROR-NO-FS' => array(
+ l10n('File/directory read error'),
+ l10n('The file or directory cannot be accessed (either it does not exist or the access is denied)')
+ ),
+ );
+$errors = array();
+$infos = array();
+
+if ($site_is_remote)
+{
+ fatal_error('remote sites not supported');
+}
+else
+{
+ include_once( PHPWG_ROOT_PATH.'admin/site_reader_local.php');
+ $site_reader = new LocalSiteReader($site_url);
+}
+
+if (isset($page['no_md5sum_number']))
+{
+ $template->assign(
+ array(
+ 'save_error' => ''.l10n('Some checksums are missing.').'',
+ )
+ );
+
+}
+
+// +-----------------------------------------------------------------------+
+// | tabs |
+// +-----------------------------------------------------------------------+
+
+include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
+$my_base_url = get_root_url().'admin.php?page=';
+
+$tabsheet = new tabsheet();
+$tabsheet->set_id('site_update');
+$tabsheet->select('synchronization');
+$tabsheet->assign();
+
+// +-----------------------------------------------------------------------+
+// | Quick sync |
+// +-----------------------------------------------------------------------+
+
+if (isset($_GET['quick_sync']))
+{
+ check_pwg_token();
+
+ $_POST['sync'] = 'files';
+ $_POST['display_info'] = '1';
+ $_POST['add_to_caddie'] = '1';
+ $_POST['privacy_level'] = '0';
+ $_POST['sync_meta'] = '1';
+ $_POST['simulate'] = '0';
+ $_POST['subcats-included'] = '1';
+ $_POST['submit'] = 'Quick Local Synchronization';
+}
+
+$general_failure = true;
+if (isset($_POST['submit']))
+{
+
+ if ($site_reader->open())
+ {
+ $general_failure = false;
+ }
+
+ // shall we simulate only
+ if (isset($_POST['simulate']) and $_POST['simulate'] == 1)
+ {
+ $simulate = true;
+ }
+ else
+ {
+ $simulate = false;
+ }
+}
+
+// +-----------------------------------------------------------------------+
+// | directories / categories |
+// +-----------------------------------------------------------------------+
+if (isset($_POST['submit'])
+ and ($_POST['sync'] == 'dirs' or $_POST['sync'] == 'files'))
+{
+ $counts['new_categories'] = 0;
+ $counts['del_categories'] = 0;
+ $counts['del_elements'] = 0;
+ $counts['new_elements'] = 0;
+ $counts['upd_elements'] = 0;
+}
+
+
+if (isset($_POST['submit'])
+ and ($_POST['sync'] == 'dirs' or $_POST['sync'] == 'files')
+ and !$general_failure)
+{
+ $start = get_moment();
+ // which categories to update ?
+ $query = '
+SELECT id, uppercats, global_rank, status, visible
+ FROM '.CATEGORIES_TABLE.'
+ WHERE dir IS NOT NULL
+ AND site_id = '.$site_id;
+ if (isset($_POST['cat']) and is_numeric($_POST['cat']))
+ {
+ if (isset($_POST['subcats-included']) and $_POST['subcats-included'] == 1)
+ {
+ $query.= '
+ AND uppercats '.DB_REGEX_OPERATOR.' \'(^|,)'.$_POST['cat'].'(,|$)\'
+';
+ }
+ else
+ {
+ $query.= '
+ AND id = '.$_POST['cat'].'
+';
+ }
+ }
+ $db_categories = hash_from_query($query, 'id');
+
+ // get categort full directories in an array for comparison with file
+ // system directory tree
+ $db_fulldirs = get_fulldirs(array_keys($db_categories));
+
+ // what is the base directory to search file system sub-directories ?
+ if (isset($_POST['cat']) and is_numeric($_POST['cat']))
+ {
+ $basedir = $db_fulldirs[$_POST['cat']];
+ }
+ else
+ {
+ $basedir = preg_replace('#/*$#', '', $site_url);
+ }
+
+ // we need to have fulldirs as keys to make efficient comparison
+ $db_fulldirs = array_flip($db_fulldirs);
+
+ // finding next rank for each id_uppercat. By default, each category id
+ // has 1 for next rank on its sub-categories to create
+ $next_rank['NULL'] = 1;
+
+ $query = '
+SELECT id
+ FROM '.CATEGORIES_TABLE;
+ $result = pwg_query($query);
+ while ($row = pwg_db_fetch_assoc($result))
+ {
+ $next_rank[$row['id']] = 1;
+ }
+
+ // let's see if some categories already have some sub-categories...
+ $query = '
+SELECT id_uppercat, MAX(`rank`)+1 AS next_rank
+ FROM '.CATEGORIES_TABLE.'
+ GROUP BY id_uppercat';
+ $result = pwg_query($query);
+ while ($row = pwg_db_fetch_assoc($result))
+ {
+ // for the id_uppercat NULL, we write 'NULL' and not the empty string
+ if (!isset($row['id_uppercat']) or $row['id_uppercat'] == '')
+ {
+ $row['id_uppercat'] = 'NULL';
+ }
+ $next_rank[$row['id_uppercat']] = $row['next_rank'];
+ }
+
+ // next category id available
+ $next_id = pwg_db_nextval('id', CATEGORIES_TABLE);
+
+ // retrieve sub-directories fulldirs from the site reader
+ $fs_fulldirs = $site_reader->get_full_directories($basedir);
+
+ // get_full_directories doesn't include the base directory, so if it's a
+ // category directory, we need to include it in our array
+ if (isset($_POST['cat']))
+ {
+ $fs_fulldirs[] = $basedir;
+ }
+ // If $_POST['subcats-included'] != 1 ("Search in sub-albums" is unchecked)
+ // $db_fulldirs doesn't include any subdirectories and $fs_fulldirs does
+ // So $fs_fulldirs will be limited to the selected basedir
+ // (if that one is in $fs_fulldirs)
+ if (!isset($_POST['subcats-included']) or $_POST['subcats-included'] != 1)
+ {
+ $fs_fulldirs = array_intersect($fs_fulldirs, array_keys($db_fulldirs));
+ }
+ $inserts = array();
+ // new categories are the directories not present yet in the database
+ foreach (array_diff($fs_fulldirs, array_keys($db_fulldirs)) as $fulldir)
+ {
+ $dir = basename($fulldir);
+ if (preg_match($conf['sync_chars_regex'], $dir))
+ {
+ $insert = array(
+ 'id' => $next_id++,
+ 'dir' => $dir,
+ 'name' => str_replace('_', ' ', $dir),
+ 'site_id' => $site_id,
+ 'commentable' =>
+ boolean_to_string($conf['newcat_default_commentable']),
+ 'status' => $conf['newcat_default_status'],
+ 'visible' => boolean_to_string($conf['newcat_default_visible']),
+ );
+
+ if (isset($db_fulldirs[dirname($fulldir)]))
+ {
+ $parent = $db_fulldirs[dirname($fulldir)];
+
+ $insert['id_uppercat'] = $parent;
+ $insert['uppercats'] =
+ $db_categories[$parent]['uppercats'].','.$insert['id'];
+ $insert['rank'] = $next_rank[$parent]++;
+ $insert['global_rank'] =
+ $db_categories[$parent]['global_rank'].'.'.$insert['rank'];
+ if ('private' == $db_categories[$parent]['status'])
+ {
+ $insert['status'] = 'private';
+ }
+ if ('false' == $db_categories[$parent]['visible'])
+ {
+ $insert['visible'] = 'false';
+ }
+ }
+ else
+ {
+ $insert['uppercats'] = $insert['id'];
+ $insert['rank'] = $next_rank['NULL']++;
+ $insert['global_rank'] = $insert['rank'];
+ }
+
+ $inserts[] = $insert;
+ $infos[] = array(
+ 'path' => $fulldir,
+ 'info' => l10n('added'),
+ );
+
+ // add the new category to $db_categories and $db_fulldirs array
+ $db_categories[$insert['id']] =
+ array(
+ 'id' => $insert['id'],
+ 'parent' => (isset($parent)) ? $parent : Null,
+ 'status' => $insert['status'],
+ 'visible' => $insert['visible'],
+ 'uppercats' => $insert['uppercats'],
+ 'global_rank' => $insert['global_rank']
+ );
+ $db_fulldirs[$fulldir] = $insert['id'];
+ $next_rank[$insert['id']] = 1;
+ }
+ else
+ {
+ $errors[] = array(
+ 'path' => $fulldir,
+ 'type' => 'PWG-UPDATE-1'
+ );
+ }
+ }
+
+ if (count($inserts) > 0)
+ {
+ if (!$simulate)
+ {
+ $dbfields = array(
+ 'id','dir','name','site_id','id_uppercat','uppercats','commentable',
+ 'visible','status','rank','global_rank'
+ );
+ mass_inserts(CATEGORIES_TABLE, $dbfields, $inserts);
+
+ // add default permissions to categories
+ $category_ids = array();
+ $category_up = array();
+ foreach ($inserts as $category)
+ {
+ $category_ids[] = $category['id'];
+ if (!empty($category['id_uppercat']))
+ {
+ $category_up[] = $category['id_uppercat'];
+ }
+ }
+
+ pwg_activity('album', $category_ids, 'add', array('sync'=>true));
+
+ $category_up=implode(',',array_unique($category_up));
+ if ($conf['inheritance_by_default'] and !empty($category_up))
+ {
+ $query = '
+ SELECT *
+ FROM '.GROUP_ACCESS_TABLE.'
+ WHERE cat_id IN ('.$category_up.')
+ ;';
+ $result = pwg_query($query);
+ if (!empty($result))
+ {
+ $granted_grps = array();
+ while ($row = pwg_db_fetch_assoc($result))
+ {
+ if (!isset($granted_grps[$row['cat_id']]))
+ {
+ $granted_grps[$row['cat_id']]=array();
+ }
+ // TODO: explanaition
+ array_push(
+ $granted_grps,
+ array(
+ $row['cat_id'] => array_push($granted_grps[$row['cat_id']],$row['group_id'])
+ )
+ );
+ }
+ }
+ $query = '
+ SELECT *
+ FROM '.USER_ACCESS_TABLE.'
+ WHERE cat_id IN ('.$category_up.')
+ ;';
+ $result = pwg_query($query);
+ if (!empty($result))
+ {
+ $granted_users = array();
+ while ($row = pwg_db_fetch_assoc($result))
+ {
+ if (!isset($granted_users[$row['cat_id']]))
+ {
+ $granted_users[$row['cat_id']]=array();
+ }
+ // TODO: explanaition
+ array_push(
+ $granted_users,
+ array(
+ $row['cat_id'] => array_push($granted_users[$row['cat_id']],$row['user_id'])
+ )
+ );
+ }
+ }
+ $insert_granted_users=array();
+ $insert_granted_grps=array();
+ foreach ($category_ids as $ids)
+ {
+ $parent_id=$db_categories[$ids]['parent'];
+ while (in_array($parent_id, $category_ids))
+ {
+ $parent_id= $db_categories[$parent_id]['parent'];
+ }
+ if ($db_categories[$ids]['status']=='private' and !is_null($parent_id))
+ {
+ if (isset($granted_grps[$parent_id]))
+ {
+ foreach ($granted_grps[$parent_id] as $granted_grp)
+ {
+ $insert_granted_grps[] = array(
+ 'group_id' => $granted_grp,
+ 'cat_id' => $ids
+ );
+ }
+ }
+ if (isset($granted_users[$parent_id]))
+ {
+ foreach ($granted_users[$parent_id] as $granted_user)
+ {
+ $insert_granted_users[] = array(
+ 'user_id' => $granted_user,
+ 'cat_id' => $ids
+ );
+ }
+ }
+ }
+ }
+ mass_inserts(GROUP_ACCESS_TABLE, array('group_id','cat_id'), $insert_granted_grps);
+ $insert_granted_users=array_unique($insert_granted_users, SORT_REGULAR);
+ mass_inserts(USER_ACCESS_TABLE, array('user_id','cat_id'), $insert_granted_users);
+ }
+ else
+ {
+ add_permission_on_category($category_ids, get_admins());
+ }
+ }
+
+ $counts['new_categories'] = count($inserts);
+ }
+
+ // to delete categories
+ $to_delete = array();
+ $to_delete_derivative_dirs = array();
+
+ foreach (array_diff(array_keys($db_fulldirs), $fs_fulldirs) as $fulldir)
+ {
+ $to_delete[] = $db_fulldirs[$fulldir];
+ unset($db_fulldirs[$fulldir]);
+
+ $infos[] = array(
+ 'path' => $fulldir,
+ 'info' => l10n('deleted')
+ );
+
+ if (substr_compare($fulldir, '../', 0, 3)==0)
+ {
+ $fulldir = substr($fulldir, 3);
+ }
+ $to_delete_derivative_dirs[] = PHPWG_ROOT_PATH.PWG_DERIVATIVE_DIR.$fulldir;
+ }
+
+ if (count($to_delete) > 0)
+ {
+ if (!$simulate)
+ {
+ delete_categories($to_delete);
+ foreach($to_delete_derivative_dirs as $to_delete_dir)
+ {
+ if (is_dir($to_delete_dir))
+ {
+ clear_derivative_cache_rec($to_delete_dir, '#.+#');
+ }
+ }
+ }
+ $counts['del_categories'] = count($to_delete);
+ }
+
+ $template->append('footer_elements', '' );
+}
+// +-----------------------------------------------------------------------+
+// | files / elements |
+// +-----------------------------------------------------------------------+
+if (isset($_POST['submit']) and $_POST['sync'] == 'files'
+ and !$general_failure)
+{
+ $start_files = get_moment();
+ $start= $start_files;
+
+ $fs = $site_reader->get_elements($basedir);
+
+ $template->append('footer_elements', '' );
+
+ $cat_ids = array_diff(array_keys($db_categories), $to_delete);
+
+ $db_elements = array();
+
+ if (count($cat_ids) > 0)
+ {
+ $query = '
+SELECT id, path
+ FROM '.IMAGES_TABLE.'
+ WHERE storage_category_id IN ('
+ .wordwrap(
+ implode(', ', $cat_ids),
+ 160,
+ "\n"
+ ).')';
+ $db_elements = simple_hash_from_query($query, 'id', 'path');
+ }
+
+ // next element id available
+ $next_element_id = pwg_db_nextval('id', IMAGES_TABLE);
+
+ $start = get_moment();
+
+ $inserts = array();
+ $insert_links = array();
+ $insert_formats = array();
+ $formats_to_delete = array();
+
+ foreach (array_diff(array_keys($fs), $db_elements) as $path)
+ {
+ $insert = array();
+ // storage category must exist
+ $dirname = dirname($path);
+ if (!isset($db_fulldirs[$dirname]))
+ {
+ continue;
+ }
+ $filename = basename($path);
+ if (!preg_match($conf['sync_chars_regex'], $filename))
+ {
+ $errors[] = array(
+ 'path' => $path,
+ 'type' => 'PWG-UPDATE-1'
+ );
+
+ continue;
+ }
+
+ $insert = array(
+ 'id' => $next_element_id++,
+ 'file' => pwg_db_real_escape_string($filename),
+ 'name' => pwg_db_real_escape_string(get_name_from_file($filename)),
+ 'date_available' => CURRENT_DATE,
+ 'path' => pwg_db_real_escape_string($path),
+ 'representative_ext' => $fs[$path]['representative_ext'],
+ 'storage_category_id' => $db_fulldirs[$dirname],
+ 'added_by' => $user['id'],
+ );
+
+ if ( $_POST['privacy_level']!=0 )
+ {
+ $insert['level'] = $_POST['privacy_level'];
+ }
+
+ $inserts[] = $insert;
+
+ $insert_links[] = array(
+ 'image_id' => $insert['id'],
+ 'category_id' => $insert['storage_category_id'],
+ );
+
+ $infos[] = array(
+ 'path' => $insert['path'],
+ 'info' => l10n('added')
+ );
+
+ if ($conf['enable_formats'])
+ {
+ foreach ($fs[$path]['formats'] as $ext => $filesize)
+ {
+ $insert_formats[] = array(
+ 'image_id' => $insert['id'],
+ 'ext' => $ext,
+ 'filesize' => $filesize,
+ );
+
+ $infos[] = array(
+ 'path' => $insert['path'],
+ 'info' => l10n('format %s added', $ext)
+ );
+ }
+ }
+
+ $caddiables[] = $insert['id'];
+ }
+
+ // search new/removed formats on photos already registered in database
+ if ($conf['enable_formats'])
+ {
+ $db_elements_flip = array_flip($db_elements);
+
+ $existing_ids = array();
+
+ foreach (array_intersect_key($fs, $db_elements_flip) as $path => $existing)
+ {
+ $existing_ids[] = $db_elements_flip[$path];
+ }
+
+ $logger->debug('existing_ids', 'sync', $existing_ids);
+
+ if (count($existing_ids) > 0)
+ {
+ $db_formats = array();
+
+ // find formats for existing photos (already in database)
+ $query = '
+SELECT *
+ FROM '.IMAGE_FORMAT_TABLE.'
+ WHERE image_id IN ('.implode(',', $existing_ids).')
+;';
+ $result = pwg_query($query);
+ while ($row = pwg_db_fetch_assoc($result))
+ {
+ if (!isset($db_formats[$row['image_id']]))
+ {
+ $db_formats[$row['image_id']] = array();
+ }
+
+ $db_formats[$row['image_id']][$row['ext']] = $row['format_id'];
+ }
+
+ // first we search the formats that were removed
+ foreach ($db_formats as $image_id => $formats)
+ {
+ $image_formats_to_delete = array_diff_key($formats, $fs[ $db_elements[$image_id] ]['formats']);
+ $logger->debug('image_formats_to_delete', 'sync', $image_formats_to_delete);
+ foreach ($image_formats_to_delete as $ext => $format_id)
+ {
+ $formats_to_delete[] = $format_id;
+
+ $infos[] = array(
+ 'path' => $db_elements[$image_id],
+ 'info' => l10n('format %s removed', $ext)
+ );
+ }
+ }
+
+ // then we search for new formats on existing photos
+ foreach ($existing_ids as $image_id)
+ {
+ $path = $db_elements[$image_id];
+
+ $formats = array();
+ if (isset($db_formats[$image_id]))
+ {
+ $formats = $db_formats[$image_id];
+ }
+
+ $image_formats_to_insert = array_diff_key($fs[$path]['formats'], $formats);
+ $logger->debug('image_formats_to_insert', 'sync', $image_formats_to_insert);
+ foreach ($image_formats_to_insert as $ext => $filesize)
+ {
+ $insert_formats[] = array(
+ 'image_id' => $image_id,
+ 'ext' => $ext,
+ 'filesize' => $filesize,
+ );
+
+ $infos[] = array(
+ 'path' => $db_elements[$image_id],
+ 'info' => l10n('format %s added', $ext)
+ );
+ }
+ }
+ }
+ }
+
+
+ if (!$simulate)
+ {
+ // inserts all new elements
+ if (count($inserts) > 0)
+ {
+ mass_inserts(
+ IMAGES_TABLE,
+ array_keys($inserts[0]),
+ $inserts
+ );
+
+ // inserts all links between new elements and their storage category
+ mass_inserts(
+ IMAGE_CATEGORY_TABLE,
+ array_keys($insert_links[0]),
+ $insert_links
+ );
+
+ pwg_activity('photo', $caddiables, 'add', array('sync'=>true));
+
+ // add new photos to caddie
+ if (isset($_POST['add_to_caddie']) and $_POST['add_to_caddie'] == 1)
+ {
+ fill_caddie($caddiables);
+ }
+ }
+
+ // inserts all formats
+ if (count($insert_formats) > 0)
+ {
+ mass_inserts(
+ IMAGE_FORMAT_TABLE,
+ array_keys($insert_formats[0]),
+ $insert_formats
+ );
+ }
+
+ if (count($formats_to_delete) > 0)
+ {
+ $query = '
+DELETE
+ FROM '.IMAGE_FORMAT_TABLE.'
+ WHERE format_id IN ('.implode(',', $formats_to_delete).')
+;';
+ pwg_query($query);
+ }
+ }
+
+ $counts['new_elements'] = count($inserts);
+
+ // delete elements that are in database but not in the filesystem
+ $to_delete_elements = array();
+ foreach (array_diff($db_elements, array_keys($fs)) as $path)
+ {
+ $to_delete_elements[] = array_search($path, $db_elements);
+ $infos[] = array(
+ 'path' => $path,
+ 'info' => l10n('deleted')
+ );
+ }
+ if (count($to_delete_elements) > 0)
+ {
+ if (!$simulate)
+ {
+ delete_elements($to_delete_elements);
+ }
+ $counts['del_elements'] = count($to_delete_elements);
+ }
+
+ $template->append('footer_elements', '' );
+}
+
+// +-----------------------------------------------------------------------+
+// | synchronize files |
+// +-----------------------------------------------------------------------+
+if (isset($_POST['submit'])
+ and ($_POST['sync'] == 'dirs' or $_POST['sync'] == 'files')
+ and !$general_failure )
+{
+ if (!$simulate)
+ {
+ $start = get_moment();
+ update_category('all');
+ $template->append('footer_elements', '' );
+ $start = get_moment();
+ update_global_rank();
+ $template->append('footer_elements', '');
+ }
+
+ if ($_POST['sync'] == 'files')
+ {
+ $start = get_moment();
+ $opts['category_id'] = '';
+ $opts['recursive'] = true;
+ if (isset($_POST['cat']))
+ {
+ $opts['category_id'] = $_POST['cat'];
+ if (!isset($_POST['subcats-included']) or $_POST['subcats-included'] != 1)
+ {
+ $opts['recursive'] = false;
+ }
+ }
+ $files = get_filelist($opts['category_id'], $site_id,
+ $opts['recursive'],
+ false);
+ $template->append('footer_elements', '');
+ $start = get_moment();
+
+ $datas = array();
+ foreach ( $files as $id=>$file )
+ {
+ $file = $file['path'];
+ $data = $site_reader->get_element_update_attributes($file);
+ if ( !is_array($data) )
+ {
+ continue;
+ }
+
+ $data['id']=$id;
+ $datas[] = $data;
+ } // end foreach file
+
+ $counts['upd_elements'] = count($datas);
+ if (!$simulate and count($datas)>0 )
+ {
+ mass_updates(
+ IMAGES_TABLE,
+ // fields
+ array(
+ 'primary' => array('id'),
+ 'update' => $site_reader->get_update_attributes(),
+ ),
+ $datas
+ );
+ }
+ $template->append('footer_elements', '');
+ }// end if sync files
+}
+
+// +-----------------------------------------------------------------------+
+// | synchronize files |
+// +-----------------------------------------------------------------------+
+if (isset($_POST['submit'])
+ and ($_POST['sync'] == 'dirs' or $_POST['sync'] == 'files'))
+{
+ $template->assign(
+ 'update_result',
+ array(
+ 'NB_NEW_CATEGORIES'=>$counts['new_categories'],
+ 'NB_DEL_CATEGORIES'=>$counts['del_categories'],
+ 'NB_NEW_ELEMENTS'=>$counts['new_elements'],
+ 'NB_DEL_ELEMENTS'=>$counts['del_elements'],
+ 'NB_UPD_ELEMENTS'=>$counts['upd_elements'],
+ 'NB_ERRORS'=>count($errors),
+ ));
+}
+
+// +-----------------------------------------------------------------------+
+// | synchronize metadata |
+// +-----------------------------------------------------------------------+
+if (isset($_POST['submit']) and isset($_POST['sync_meta'])
+ and !$general_failure)
+{
+ // sync only never synchronized files ?
+ $opts['only_new'] = isset($_POST['meta_all']) ? false : true;
+ $opts['category_id'] = '';
+ $opts['recursive'] = true;
+
+ if (isset($_POST['cat']))
+ {
+ $opts['category_id'] = $_POST['cat'];
+ // recursive ?
+ if (!isset($_POST['subcats-included']) or $_POST['subcats-included'] != 1)
+ {
+ $opts['recursive'] = false;
+ }
+ }
+ $start = get_moment();
+ $files = get_filelist($opts['category_id'], $site_id,
+ $opts['recursive'],
+ $opts['only_new']);
+
+ $template->append('footer_elements', '');
+
+ $start = get_moment();
+ $datas = array();
+ $tags_of = array();
+
+ foreach ( $files as $id => $element_infos )
+ {
+ $data = $site_reader->get_element_metadata($element_infos);
+
+ if ( is_array($data) )
+ {
+ $data['date_metadata_update'] = CURRENT_DATE;
+ $data['id']=$id;
+ $datas[] = $data;
+
+ foreach (array('keywords', 'tags') as $key)
+ {
+ if (isset($data[$key]))
+ {
+ if (!isset($tags_of[$id]))
+ {
+ $tags_of[$id] = array();
+ }
+
+ foreach (explode(',', $data[$key]) as $tag_name)
+ {
+ $tags_of[$id][] = tag_id_from_tag_name($tag_name);
+ }
+ }
+ }
+ }
+ else
+ {
+ $errors[] = array(
+ 'path' => $element_infos['path'],
+ 'type' => 'PWG-ERROR-NO-FS'
+ );
+ }
+ }
+
+ if (!$simulate)
+ {
+ if (count($datas) > 0)
+ {
+ mass_updates(
+ IMAGES_TABLE,
+ // fields
+ array(
+ 'primary' => array('id'),
+ 'update' => array_unique(
+ array_merge(
+ array_diff(
+ $site_reader->get_metadata_attributes(),
+ // keywords and tags fields are managed separately
+ array('keywords', 'tags')
+ ),
+ array('date_metadata_update'))
+ )
+ ),
+ $datas,
+ isset($_POST['meta_empty_overrides']) ? 0 : MASS_UPDATES_SKIP_EMPTY
+ );
+ }
+ set_tags_of($tags_of);
+ }
+
+ $template->append('footer_elements', '');
+
+ $template->assign(
+ 'metadata_result',
+ array(
+ 'NB_ELEMENTS_DONE' => count($datas),
+ 'NB_ELEMENTS_CANDIDATES' => count($files),
+ 'NB_ERRORS' => count($errors),
+ ));
+}
+
+// +-----------------------------------------------------------------------+
+// | template initialization |
+// +-----------------------------------------------------------------------+
+$template->set_filenames(array('update'=>'site_update.tpl'));
+$result_title = '';
+if (isset($simulate) and $simulate)
+{
+ $result_title.= '['.l10n('Simulation').'] ';
+}
+
+// used_metadata string is displayed to inform admin which metadata will be
+// used from files for synchronization
+$used_metadata = implode( ', ', $site_reader->get_metadata_attributes());
+if ($site_is_remote and !isset($_POST['submit']) )
+{
+ $used_metadata.= ' + ...';
+}
+
+$template->assign(
+ array(
+ 'SITE_URL'=>$site_url,
+ 'U_SITE_MANAGER'=> get_root_url().'admin.php?page=site_manager',
+ 'L_RESULT_UPDATE'=>$result_title.l10n('Search for new images in the directories'),
+ 'L_RESULT_METADATA'=>$result_title.l10n('Metadata synchronization results'),
+ 'METADATA_LIST' => $used_metadata,
+ 'U_HELP' => get_root_url().'admin/popuphelp.php?page=synchronize',
+ 'ADMIN_PAGE_TITLE' => l10n('Synchronize'),
+ ));
+
+// +-----------------------------------------------------------------------+
+// | introduction : choices |
+// +-----------------------------------------------------------------------+
+if (isset($_POST['submit']))
+{
+ $tpl_introduction = array(
+ 'sync' => $_POST['sync'],
+ 'sync_meta' => isset($_POST['sync_meta']) ? true : false,
+ 'display_info' => isset($_POST['display_info']) and $_POST['display_info']==1,
+ 'add_to_caddie' => isset($_POST['add_to_caddie']) and $_POST['add_to_caddie']==1,
+ 'subcats_included' => isset($_POST['subcats-included']) and $_POST['subcats-included']==1,
+ 'privacy_level_selected' => (int)@$_POST['privacy_level'],
+ 'meta_all' => isset($_POST['meta_all']) ? true : false,
+ 'meta_empty_overrides' => isset($_POST['meta_empty_overrides']) ? true : false,
+ );
+
+ if (isset($_POST['cat']) and is_numeric($_POST['cat']))
+ {
+ $cat_selected = array($_POST['cat']);
+ }
+ else
+ {
+ $cat_selected = array();
+ }
+}
+else
+{
+ $tpl_introduction = array(
+ 'sync' => 'dirs',
+ 'sync_meta' => true,
+ 'display_info' => false,
+ 'add_to_caddie' => false,
+ 'subcats_included' => true,
+ 'privacy_level_selected' => 0,
+ 'meta_all' => false,
+ 'meta_empty_overrides' => false,
+ );
+
+ $cat_selected = array();
+
+ if (isset($_GET['cat_id']))
+ {
+ check_input_parameter('cat_id', $_GET, false, PATTERN_ID);
+
+ $cat_selected = array($_GET['cat_id']);
+ $tpl_introduction['sync'] = 'files';
+ }
+}
+
+$tpl_introduction['privacy_level_options'] = get_privacy_level_options();
+
+$template->assign('introduction', $tpl_introduction);
+
+$query = '
+SELECT id,name,uppercats,global_rank
+ FROM '.CATEGORIES_TABLE.'
+ WHERE site_id = '.$site_id;
+display_select_cat_wrapper($query,
+ $cat_selected,
+ 'category_options',
+ false);
+
+
+if (count($errors) > 0)
+{
+ foreach ($errors as $error)
+ {
+ $template->append(
+ 'sync_errors',
+ array(
+ 'ELEMENT' => $error['path'],
+ 'LABEL' => $error['type'].' ('.$error_labels[$error['type']][0].')'
+ ));
+ }
+
+ foreach ($error_labels as $error_type=>$error_description)
+ {
+ $template->append(
+ 'sync_error_captions',
+ array(
+ 'TYPE' => $error_type,
+ 'LABEL' => $error_description[1]
+ ));
+ }
+}
+
+if (count($infos) > 0
+ and isset($_POST['display_info'])
+ and $_POST['display_info'] == 1)
+{
+ foreach ($infos as $info)
+ {
+ $template->append(
+ 'sync_infos',
+ array(
+ 'ELEMENT' => $info['path'],
+ 'LABEL' => $info['info']
+ ));
+ }
+}
+
+// +-----------------------------------------------------------------------+
+// | sending html code |
+// +-----------------------------------------------------------------------+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'update');
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/stats.php b/Piwingo/piwigo-data/piwigo/admin/stats.php
new file mode 100644
index 0000000..aabc008
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/stats.php
@@ -0,0 +1,399 @@
+format('n') - 1;
+ $query .=
+' LIMIT '.$limit;
+ $result = query2array($query.';');
+ $lastDate = $date->sub(new DateInterval('P'.($last - 1).'Y'.($date->format('n') - 1).'M'));
+ return set_missing_values('month', $result, $lastDate, new DateTime());
+ }
+
+ if (count(query2array($query.';')) > 1 )
+ {
+ return set_missing_values('month', query2array($query.';'));
+ } else {
+ $last_year_date = new DateTime();
+ return set_missing_values(
+ 'month',
+ query2array($query.';'),
+ $last_year_date->sub(new DateInterval('P1Y')),
+ new DateTime()
+ );
+ }
+}
+
+function get_month_stats()
+{
+ $result = array();
+ $date = new DateTime();
+ $date_last_month = clone $date;
+ $date_last_year = clone $date;
+ $months = array();
+
+ $date_last_month->sub(new DateInterval('P1M'));
+ $date_last_year->sub(new DateInterval('P1Y'));
+ $query = '
+SELECT
+ year,
+ month,
+ day,
+ hour,
+ nb_pages
+FROM '.HISTORY_SUMMARY_TABLE.'
+WHERE
+ (
+ (year = '.$date->format('Y').' AND month = '.$date->format('n').')
+ OR (year = '.$date_last_month->format('Y').' AND month = '.$date_last_month->format('n').')
+ OR (year = '.$date_last_year->format('Y').' AND month = '.$date_last_year->format('n').')
+ )
+ AND day IS NOT NULL
+ AND hour IS NULL
+ORDER BY
+ year DESC,
+ month DESC
+;';
+
+ foreach (query2array($query) as $value)
+ {
+ $date = get_date_object($value);
+ @$months[$date->format('Y/m/1')][] = $value;
+ }
+
+ $actual_date = new DateTime();
+ if (!isset($months[$actual_date->format('Y/m/1')]))
+ {
+ @$months[$actual_date->format('Y/m/1')][] = array(
+ 'year' => $actual_date->format('Y'),
+ 'month'=> $actual_date->format('n'),
+ 'day'=> null,
+ 'hour'=> null,
+ 'nb_pages' => 0
+ );
+ }
+
+ foreach ($months as $key => $val)
+ {
+ $lastDate = new DateTime($key);
+ $lastDate = $lastDate->add(new DateInterval('P1M'));
+ $lastDate = $lastDate->sub(new DateInterval('P1D'));
+ if ($lastDate > new DateTime())
+ {
+ $lastDate = new DateTime();
+ }
+ $result['month'][] = set_missing_values('day',$val, new DateTime($key), $lastDate);
+ }
+
+ $query = '
+SELECT
+ AVG(nb_pages)
+FROM '.HISTORY_SUMMARY_TABLE.'
+WHERE
+ (
+ year = '.$date->format('Y').' OR
+ (year = '.($date->format('Y')-1).' and month > '.$date->format('n').')
+ )
+ AND day IS NOT NULL
+ AND hour IS NULL
+ORDER BY
+ year DESC,
+ month DESC
+;';
+
+ list($result['avg']) = pwg_db_fetch_row(pwg_query($query));
+
+ return $result;
+}
+
+// +-----------------------------------------------------------------------+
+// | Check Access and exit when user status is not ok |
+// +-----------------------------------------------------------------------+
+
+check_status(ACCESS_ADMINISTRATOR);
+
+// +-----------------------------------------------------------------------+
+// | Refresh summary from details |
+// +-----------------------------------------------------------------------+
+
+history_summarize();
+
+// +-----------------------------------------------------------------------+
+// | Display statistics header |
+// +-----------------------------------------------------------------------+
+
+$template->set_filename('stats', 'stats.tpl');
+
+// TabSheet initialization
+history_tabsheet();
+
+$base_url = get_root_url().'admin.php?page=history';
+
+$template->assign(
+ array(
+ 'U_HELP' => get_root_url().'admin/popuphelp.php?page=history',
+ 'F_ACTION' => $base_url,
+ )
+ );
+
+// +-----------------------------------------------------------------------+
+// | Set missing rows to 0 |
+// +-----------------------------------------------------------------------+
+
+function set_missing_values($unit, $data, $firstDate = null, $lastDate = null)
+{
+ $limit = count($data);
+ $result = array();
+
+ if ($firstDate == null)
+ {
+ $date = get_date_object($data[count($data) - 1]);
+ } else {
+ $date = $firstDate;
+ }
+ if ($lastDate == null)
+ {
+ $date_end = get_date_object($data[0]);
+ } else {
+ $date_end = $lastDate;
+ }
+
+ //Declare variable according the unit
+ if ($unit == 'year')
+ {
+ $date_format = 'Y';
+ $date_add = 'P1Y';
+ }
+ else if ($unit == 'month')
+ {
+ $date_format = 'Y-m';
+ $date_add = 'P1M';
+ }
+ else if ($unit == 'day')
+ {
+ $date_format = 'Y-m-d';
+ $date_add = 'P1D';
+ }
+ else if ($unit == 'hour')
+ {
+ $date_format = 'Y-m-d\TH:00';
+ $date_add = 'PT1H';
+ }
+
+ //Fill an empty array with all the dates
+ while ($date <= $date_end) {
+ $result[$date->format($date_format)] = 0;
+ $date->add(new DateInterval($date_add));
+ }
+
+ //Overload with database rows
+ foreach ($data as $value)
+ {
+ $str = get_date_object($value)->format($date_format);
+ if (isset($result[$str]))
+ {
+ $result[$str] += $value['nb_pages'];
+ }
+ }
+
+ return $result;
+}
+
+//Get a DateTime object for a database row
+function get_date_object($row)
+{
+ $date_string = $row['year'];
+ if ($row['month'] != null)
+ {
+ $date_string = $date_string.'-'.$row['month'] ;
+ if ($row['day'] != null)
+ {
+ $date_string = $date_string.'-'.$row['day'];
+ if ($row['hour'] != null)
+ {
+ $date_string = $date_string.' '.$row['hour'].':00';
+ }
+ }
+ }
+ else
+ {
+ $date_string .= '-1';
+ }
+
+ return new DateTime($date_string);
+}
+
+// +-----------------------------------------------------------------------+
+// | Send data to template |
+// +-----------------------------------------------------------------------+
+
+$actual_date = new DateTime();
+$actual_date->add(new DateInterval('PT1S'));
+
+$first_date = new DateTime();
+$last_hours = set_missing_values(
+ 'hour',
+ get_last(72, 'hour'),
+ $first_date->sub(new DateInterval("P3D")),
+ $actual_date
+);
+
+$first_date = new DateTime();
+$last_days = set_missing_values(
+ 'day',
+ get_last(90, 'day'),
+ $first_date->sub(new DateInterval("P90D")),
+ $actual_date
+);
+
+$first_date = new DateTime();
+$last_months = set_missing_values(
+ 'month',
+ get_last(60, 'month'),
+ $first_date->sub(new DateInterval("P60M")),
+ $actual_date
+);
+
+if (count(get_last(60, 'year')) > 1 )
+{
+ $last_years = set_missing_values(
+ 'year',
+ get_last(60, 'year')
+ );
+} else {
+ $last_year_date = new DateTime();
+ $last_years = set_missing_values(
+ 'year',
+ get_last(60, 'year'),
+ $last_year_date->sub(new DateInterval('P1Y')),
+ new DateTime()
+ );
+}
+
+ksort($lang['month']);
+
+$template->assign(array(
+ 'compareYears' => get_month_of_last_years($conf['stat_compare_year_displayed']),
+ 'monthStats' => get_month_stats(),
+ 'lastHours' => $last_hours,
+ 'lastDays' => $last_days,
+ 'lastMonths' => $last_months,
+ 'lastYears' => $last_years,
+ 'langCode' => strval($user['language']),
+ 'month_labels' => join('~', $lang['month']),
+ 'ADMIN_PAGE_TITLE' => l10n('History'),
+));
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'stats');
+?>
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/tags.php b/Piwingo/piwigo-data/piwigo/admin/tags.php
new file mode 100644
index 0000000..58cc5fe
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/tags.php
@@ -0,0 +1,165 @@
+set_id('tags');
+$tabsheet->select('');
+$tabsheet->assign();
+
+// +-----------------------------------------------------------------------+
+// | delete orphan tags |
+// +-----------------------------------------------------------------------+
+
+if (isset($_GET['action']) and 'delete_orphans' == $_GET['action'])
+{
+ check_pwg_token();
+
+ delete_orphan_tags();
+ $_SESSION['message_tags'] = l10n('Orphan tags deleted');
+ redirect(get_root_url().'admin.php?page=tags');
+}
+
+// +-----------------------------------------------------------------------+
+// | template init |
+// +-----------------------------------------------------------------------+
+
+$template->set_filenames(array('tags' => 'tags.tpl'));
+
+$template->assign(
+ array(
+ 'F_ACTION' => PHPWG_ROOT_PATH.'admin.php?page=tags',
+ 'PWG_TOKEN' => get_pwg_token(),
+ )
+ );
+
+// +-----------------------------------------------------------------------+
+// | orphan tags |
+// +-----------------------------------------------------------------------+
+
+$warning_tags = "";
+
+$orphan_tags = get_orphan_tags();
+
+$orphan_tag_names_array = '[]';
+$orphan_tag_names = array();
+foreach ($orphan_tags as $tag)
+{
+ $orphan_tag_names[] = trigger_change('render_tag_name', $tag['name'], $tag);
+}
+
+if (count($orphan_tag_names) > 0)
+{
+ $warning_tags = sprintf(
+ l10n('You have %d orphan tags %s'),
+ count($orphan_tag_names),
+ ''
+ .l10n('Review').''
+ );
+
+ $orphan_tag_names_array = '["';
+ $orphan_tag_names_array.= implode(
+ '" ,"',
+ array_map(
+ 'htmlentities',
+ $orphan_tag_names,
+ array_fill(0 , count($orphan_tag_names) , ENT_QUOTES)
+ )
+ );
+ $orphan_tag_names_array.= '"]';
+}
+
+$template->assign(
+ array(
+ 'orphan_tag_names_array' => $orphan_tag_names_array,
+ 'warning_tags' => $warning_tags,
+ )
+ );
+
+$message_tags = '';
+if (isset($_SESSION['message_tags']))
+{
+ $message_tags = $_SESSION['message_tags'];
+ unset($_SESSION['message_tags']);
+}
+$template->assign('message_tags', $message_tags);
+
+// +-----------------------------------------------------------------------+
+// | form creation |
+// +-----------------------------------------------------------------------+
+$per_page = 100;
+
+// tag counters
+$query = '
+SELECT tag_id, COUNT(image_id) AS counter
+ FROM '.IMAGE_TAG_TABLE.'
+ GROUP BY tag_id';
+$tag_counters = simple_hash_from_query($query, 'tag_id', 'counter');
+
+// all tags
+$query = '
+SELECT name, id, url_name
+ FROM '.TAGS_TABLE.'
+;';
+$result = pwg_query($query);
+$all_tags = array();
+while ($tag = pwg_db_fetch_assoc($result))
+{
+ $raw_name = $tag['name'];
+ $tag['raw_name'] = $raw_name;
+ $tag['name'] = trigger_change('render_tag_name', $raw_name, $tag);
+ $counter = intval(@$tag_counters[ $tag['id'] ]);
+ if ($counter > 0)
+ {
+ $tag['counter'] = intval(@$tag_counters[ $tag['id'] ]);
+ }
+
+ $alt_names = trigger_change('get_tag_alt_names', array(), $raw_name);
+ $alt_names = array_diff( array_unique($alt_names), array($tag['name']) );
+ if (count($alt_names))
+ {
+ $tag['alt_names'] = implode(', ', $alt_names);
+ }
+ $all_tags[] = $tag;
+}
+usort($all_tags, 'tag_alpha_compare');
+
+$template->assign(
+ array(
+ 'first_tags' => array_slice($all_tags, 0, $per_page),
+ 'data' => $all_tags,
+ 'total' => count($all_tags),
+ 'per_page' => $per_page,
+ 'ADMIN_PAGE_TITLE' => l10n('Tags'),
+ )
+ );
+
+// +-----------------------------------------------------------------------+
+// | sending html code |
+// +-----------------------------------------------------------------------+
+
+$template->assign_var_from_handle('ADMIN_CONTENT', 'tags');
+
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/theme.php b/Piwingo/piwigo-data/piwigo/admin/theme.php
new file mode 100644
index 0000000..a71098b
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/theme.php
@@ -0,0 +1,38 @@
+fs_themes)))
+{
+ die('Invalid theme');
+}
+
+$filename = PHPWG_THEMES_PATH.$_GET['theme'].'/admin/admin.inc.php';
+if (is_file($filename))
+{
+ include_once($filename);
+}
+else
+{
+ die('Missing file '.$filename);
+}
+?>
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/themes.php b/Piwingo/piwigo-data/piwigo/admin/themes.php
new file mode 100644
index 0000000..4beeb6a
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/themes.php
@@ -0,0 +1,36 @@
+set_id('themes');
+$tabsheet->select($page['tab']);
+$tabsheet->assign();
+
+if ($page['tab'] == 'update') {
+ include(PHPWG_ROOT_PATH.'admin/updates_ext.php');
+ $template->assign('ADMIN_PAGE_TITLE', l10n('Themes'));
+}
+else
+{
+ include(PHPWG_ROOT_PATH.'admin/themes_'.$page['tab'].'.php');
+}
+?>
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/themes/clear/css/components/general.css b/Piwingo/piwigo-data/piwigo/admin/themes/clear/css/components/general.css
new file mode 100644
index 0000000..e69de29
diff --git a/Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/cat_move.png b/Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/cat_move.png
new file mode 100644
index 0000000000000000000000000000000000000000..b3f937614626c88083a0326b27522eb1ad193efc
GIT binary patch
literal 249
zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6U4S$Y
z{B+)352QE?JR*x37`TN&n2}-D90{Nxdx@v7EBhTL5iWT)Rol~wK%q)c7sn8b)5#%0
zK}ic(3=9J}*tRnY@$m5cUKr67!mJ`8A#u&vz@Wh4V^vJs1EU0WW@ct_se7Hiirjq6
zUlx9e)mYnenp=nEP)B=!f{;-|cMNmgqX(OXr8_Z5
literal 0
HcmV?d00001
diff --git a/Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/category_children.png b/Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/category_children.png
new file mode 100644
index 0000000000000000000000000000000000000000..7205c3f61a10e0f3232bf40b3b07571c66f91620
GIT binary patch
literal 1554
zcmV+t2JQKYP)ze`{aPH{X0SlVoNR
zGD(v*nMsK=No<3(kcVQmG?p|dp+-=O5k$e4qECV#KKK$}y!1hkQhd=WN@AfZQeU(c
z+N3eln%0h)%#69Vley%(oH^$^=j^?F_$Clr3L`(z<;Kz3~
zX6{x=00l;XPXPA-13(QZf%^vr2EO*iFC8f+KR|GRQ0EKD`0>K
zJdq^HulMe~e{f`ESgkdL5GBuZwZ_U*$Dat>b_~&MHI0bS-#4J&{m!#-c6Q!~$Ujx}
zD{{v^b=_q>`GAN_pFH`!@yV&(WhZTk5m7`CKn!xLxop$5HSyl5s$z^tSw@||bS?b+
z`BQFnwfTwzVsEd4YOi~14MkBt^~fWK#y>W>yFBy8YcBB#NbiUUBH+BoIZF|P7$XE!
zjX@rIc%S*(tLHiM`t-O1_Qe>#86&%ZKESGK4oplezcn{F;fL|OvdicNt5AKh~7z1ckR+4wSx@pr!P1BB8Ti0eY
zqbLfBq9B9{)rc5j=gw{P_t(kufVBoyCGiO&0w50XCr&)gv13QV^6HXWYuBFw>2?bP
zXpAaVRZ*5DdEO;W*Jw3cT)ldo-~Q%BcHX;{4I76DA@)9v^;A^=2o~71cysYnhd=Wu
zOH0dkZ7r8HT{CIACPh)u?G{oL1u-ht_Et1FIKbx3BkbEh$;9|Be)Yod*sx)UstS}v
ziHKolW=?M0SX{9pa$#Zq^5+j8JTS8Vz+}wxT)cN;j36QyV{y*oeS&uhRVXRTf}$u{
zU0G$vj_o+_`Qsn{%;wQiI%$SrbY^BwmX=noTM@~C_Jx1E``P2iKNpNKR#jC*#9EJY
z3Ep|Ut6{Ar%Thv!XpD#m?M{cOslB{$W|}Kku8|}OA;dU4J7=2B_P;D3)|&H6OUs9f
zve@(F(Zf}mX0}$Vt9M?!^*C1}@qM(@TjY6$0wG3XRATJyefvFQoIdq?YDrD2Q0d&<
zg2}S{bqkpFj?bPwd;aNz2S46_@WBUSH!Dn1>r>|vNs>Cv_6n``Dj>uV(e)`*l`PBH
zzI}{~7w4FM^8)?#y3WsEHdR%%z6MG=ZE
zTXu$_!O=J}yfqFC45<}S0gW+Ig^IH5c~u3P&9+WV?AARKyO^KpU@k
zx^m^(q0^^d+_SJSuL}$FrqjtxH!oOPS&RtL7!$mA(R&}0#A_`{qIXUQ2O9C*x#{Yy
zx88Qvn%7kI2Op%V04gF4RsAaP=~^wBD9dtNj5;J@q_5tmjsAY=Z`7&R>(r72V}ux$
zX0xT2FJBesOd3Kw5@YAkMx(CYIYJCQDHRbV>V^$N(ORnj4&W!xp5*bvkCJ5>B0^OK
zsXRgl=Cbv`R&rLfa@6QeUD3f`X|xg}!zhN)`p`
zz-t0)g#Vhz{|dfuFQ6j)AShdwRBiN)#Vz`&p1jT}nUE8aEGV^9^?WVJ{^88*7>GG^
z*^9tSz&8~pn?`{TaLXyYoHu-N>xz>5*0NR#1#3bUB*{F9QxXrE2Oks(P|Li3^-RXk
zjy9sPRNoc2Tj6|DTdx|3fGX^$u5Ypnt2)y8eWJq
z(S{3BP_O;tK6~`<_55Hxyd$tiVH^~O_ob|-;h8V66EGG~E6i8e@#OMS%cf;zX;6|Y
zrEVtHJ|cyc_aTi*WbzUiL*!H3)EI-kD=0tobBZ@CC+j~TQ?b)o1#7$V;`a`_Wda9)
zQ&wiK|M%+@RBh?4*0@-*B9t68k=}k2~Mi*?Er)<#$Yhx{^r%#S-k|8A}wWf#B`nc}<>yvLqBLiWrC+~spfl*gqBg=!b&jxLf$9VwL1tj_tLJix@EJy0m4
z-jfBTEfTt048Y9>nBAH)6bu@BNIfKp!v)2j{s-x{^-NwEz~l<}EW>3P*c@(hgo{7E
zmx%*!Lb(IyJzl|wnQXO20?-`+A*hl%$RZ^us0u-pEN(E^(ZM{MM?)Y4MKypZ!3P>+
z<78g(D)^xI0A4{=3910W02ik+Wi0XHJj4#tV5m)u)8D&_xtm|1(%nNAH^5qm^7y2I
zsm!Kl>uW>{Zlf_ihQs25;uT`AOlAr&WCV^kJn_j1Z+r+eoM>FHbEfBG+_-rM)k>AP
zUPB5+{NyNZWDqH};cDa9Qibb(_(uv0K1woO$Eg8TMw1}Ji2@upMmPo>-Fq>^dqV7$
zD^t^SeEK0~b#~F1yn^J5gk*{fzu3sXzkfIB&;X{jN;*D5uHzbdAN($9nvn+7pd6bF
zCJBri*k_uv{P%BM$QYOkK?9O_R8Jql1G(xfLNdkatzTmFz;0?6&e8w9&(b(|ihTDx
zqJkwJK1=FR7gS=0-#g*}b}0XZyimT%Dz<)v(e{wberKNaV_@|U1&
zY))vkO&%y8RLT1`3n2u_{ET?ktamh!Lp4+JuU<&>*?}~-
zq+;LPa#QJ^eIqVT!VJu;ks0;1b8`Bl6=l2r!==|}S6T<2`|3mq0Pb?`u+*>s1rC8-KH0wfA)c)!GVRKHs3^G+I(_bXV=+#9{lQ`Hgr!s)$!JgCx?B}
z1RwPHgxALoPrncJ>{(xBc~=CYcIEmOYzcAb$_`43|+WjdFm=tBSi02y>e
uSaefwW^{L9a%BKPWN%_+AW3auXJt}lVPtu6$z?nM0000`TyO86Tl?^0$>opADP*?B+$L45}XLk{Bt5IUg<8|Y|rQA<;lg1
z7vuZ)@3+#^(*?jcMD)o2a7;Xp`91)L0L<9L-n{pD41ky!06Kj>pNx!*nBj2P>g?={
z6%`c;fMFuaT;fBvoZA81bh%uzXU`t1y1LpVA^}jpL~;T%8}?xxfJvXvCpT`~u%@S{
zrMtU3mYSL>0G_vf9QOW80J^NKOj=r6;+HO6vN}6EtxcOY34m{sAK?^{3tH=cG4n%x7#hNR;^;E(+L2|mNB`Pc)eaaeE4w8Fbso;XkcJKu3ftZ04JFe
zx6XUL-e*foOY^nXA1kG{o2L1U$Kyd>ULGQm2zq*YjBq#%0DU3?0G17~5dhNC(o|Mf
zmgMH=H?3f8a+iRSN?q-n9q#-vq
zS4KxiV>2@|GB-D;XJ=>i+}xZMiA419@UV!8zI^$zq^72t0KOz5^Tdf0R%2u19RNZ^
zCz<&nW_B%2UuEZTe>56>X<%R=ef|3NW;7Z_AP}JX`g&$&`2Bu-*3m%@L&?bSh}^t&
zGw1m6xaKc|o=o*GOGm
zon|HzfG~5-J$137@eeSGngGbU=l)=x`FvQ{RX0gCej`AR6csh@6&)s|LWI8A|m?W!Gk6MQA+Jjg4mL+C>4RI
z#SVU_yG(#IE7q;8t=8b+pmcS0$=KMKwR`t&3xIaJ-P=~LUi|~flZU?o
zBn3P7#+v&kbnnz`BKV(9N#PUE-660L(R%~GQYsff<^7J0*#FzTj>5cE`19o(82@UJCOSTi_kQudL!dtrkzGWz
zD-;U-v#P4fxPAL}d}3k(w{G21+qP}Pj}LxbV*
zc)oJG-G4cA=1ihX*xeL6cI?c|ejszwMURL_RmFbs)4lPBAFYT1kS$xbT&S(BO^(In
zaDr0mK>+QyQ!DS_Q?mIq&!M$Bk!ZDkR`
z{QQ5hu&{_oB#K}#$m8SV6pcm^4u?@#SO@@EyLK(w+uN~q>sBB!-3+3nf_LpZRZ5EG
z^c}P<0000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUy07*qoM6N<$
Eg47NJe*gdg
literal 0
HcmV?d00001
diff --git a/Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/category_elements.png b/Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/category_elements.png
new file mode 100644
index 0000000000000000000000000000000000000000..1038e51ce6b2049a4eb9e639fbf69c3fc6612ed1
GIT binary patch
literal 1241
zcmV;~1Sb25P)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01ejw01ejxLMWSf00007bV*G`2ipS!
z3kf3W&xSq#00db{L_t(Y$E8+VZ&Xzj{`T2tsJ0`59l4|^Mv0p01DA*qD2hQ$P!isZ
z@%E%qryU{?OiT>*#fX=1$zT=z0~$qr0b`6oYUH9Zu~fhcl?0oVQj&(5IcM*+*52EP
z8HQ=WT687*Y3;MtUf=rGw~oSpupK*gtkhcX1#q#etLyg3?y74ETr3vnYpsiMCiBp;
zsY++6{mScT=@ZRCcXP!lKbIXJmsmVC08@(TY*duYVSUl0(($coP
zW91DZ4sUFI9fPL_v2NWu#5%^BRV$&qM^FHif>INSP<^v%s5C?ozCBRwdF;KPxoFXn
zY^hX6{>2y2-rkNSOBN#p4+RC~Jyt*RFrru?1cvtl5rOv}&N+y9FncgLcq?Ec3=IBx
z89o5(e>!@&a?8AVm^t$%G&eWHdtV1KL<-_9oJ&ERfFuFCw0^`HIA`D-!FmDJ2yh9?
zs8A>zcFukM`^l4>?<(NbsnZaVdaINIm<@;x*clL8kRw>JU`HTH!OlROfjA2zG>$$I
z03=DWvH#ew=Dwv%F>CfL3=Iv{fCW?pI7c8hASRF#kO)W|hy~&VEEX&lA{Hz%o?!s6
zY15{&-uvxG4*gi!xOoePhpY3_)YJr}0817u1d%EPhCQr!SP^jTh%lH5#I~^j6dglvK1>DXaX=ZhzLXkVS!_UFu@5|eb&O-s^3}~Cq+@ipe4-wO7Fn~
zrI%jL*KarvFgcJFkR=FN2pKqQK*qot3nqcJ1Y-zHmlG(ZLe!Y9P$+zoB*`D6=g$YF
z6ciLf2uM>4G6E)nNe$RokTqaSAVV-I!5T(Vv9PJBH#vmh#wAcn1t;?Skwb?nQ502y
z^Z~{=Bncs{FxWWQlwlKwshu=ol*<+-wQ#mdQ>sA~O`P`5&dy@LyfhAQb>xPLWg?
zm_Aq{66_Ey`t!Qpv(pEWG6_v@5=vqScGIPlu|yPIMOF3TlWD%4w$l-g+3L}F4KV?U`;iKS}VG~N=UX^da$C5=gqCdQOjsudzv
zi)F<$2260dE_GQJW-l|dGw=NzKQP2XYd;uIa&k_d+j)L@a{dqecN6{(=Dp3~2Dnzd
zbNJlGoZ;0O8?D5{J;H?{OEciaK2f+glw$`b0m~&DxV>R$DV6hWC=cr=n
z8|ZGO#s_k(yc@W(dh;sF7xM;uw>3Tp{1UhZSRse{4g(V46tK$)rCX@~gCrsXn0Qjs
zR7XDh^v>RqtC!M0f9HsZlS8Jq>F&Eq9gjS)$Tq#Bz`VAmX0sJWE;Zfr$20r&k;K)S
zTy(-tHC|~^XI|^Zj{qM6HUalyY#A8p&-d-PLtI{LeE9O6_idW*AKUv-wqgBZ>Fb><
zU31!{tINs2f`I$iVcXVu*~pmQc45MHI^k~yBY^XOXNslv-3$Bs-dFA}eX#5H^44No
zTmGF}R$0&)OZTdIQYaVn*z;$cQS!EaU?YvDCu&YKQ?al~SZ_$FUA*lZTsktQxsfs3
z?u6eOO!`3on)k2fJ-gqVPFKkX-{|CMx|8@F$X@F@>?c){}CCGCS{nXFBFK^A+BxG7N<
z<2g^n6VfoHZ?KO-M~+`TeV99XyVA>xEKfdjh_
zGN&GL;5QF2&=(L@uHc6g5Ka>&Mx0*vBt_JW&NcvU^MRk8J#l``*%Rk|z{H7|TF2T)
z*STdMyUVoFls`Roi1PFdhkr4|z`P34>veKkh2|td5Yvo}ATh$kh*GmuA&3EJ`mOGK
zQJi!bmWY#*slA#j`t$uLwY|FzN>_D;gFotGp!_WpxEH@yw54+rnY*IFzkeVZ>6RNyyAJ@Da|x@YSfmmUm?ky4)JDY&7#x@5|d_RG$WV|
zje1~K4@~kobnkJsKb*h`eBNN>P5Lg^Ij-&a;F-7ztpS!dB%KJPL$G)mEG!|b*5CO>{b-QkmXp5sX~o@l+T@+Jaz9pMw-c#zK=
zd00O3?ERD%l?uRPelC9naaM3>PYLZRqE1ji*DiBMzy3*obGdl)M)JJu33
z0-Wd2SXsJp2@@Sv#1jdpLfQY-{W=fV`P4UeY`$=@GIZ|TSWmkb#w&Xo=eMq?A6c=0
zlj4-0?@!#9f12t|1@8IyM%L^eV)EKFzVCquQ8Pjl#nkYNK2as`Ui#9@+0f!%_Wk|~
zl#8?I^jW0(Pvq)Zrmlr@rKaM0reAwDVb5O_=UOPe{XLXccQHLtB?%IudW5Ems$puR
z&4gU3VEy+j;owh(y=FD=wryGF>X*kIwJB$_)5K|JQHlkzF{cAwcvUfje*@ez1wFr!
zCZ_-Z02y>eSaefwW^{L9a%BKPWN%_+AW3auXJt}lVPtu6$z?nM0000F%$ZGLVIf}}JFc69LCMbcsj=h68^?|xr|$Z7cJJPeh+tV3mo8n>OP4M+gTY{>
zVHiua{@)Ttk_k`+1qD=8RH%s)#^cZN^XebU2*#B$aCni`&=NELT(O=>KPsY6pT2C`
zw24832H|qKm^pK%ap1s#SXNfn^IGejN+}*0!!Q6Yu2```7A|}?QCYcDh7BJsyFNK6
zT12kh56k(+sI1<&L&lCBCtEgemI)IlN_~C3ghC-52n0k#bai!gS6W({0Ke=ZF%5vE
zXO}NuAvZUd+JDzDbmSNo%$h;8^#N8Q!o9lQWKdI6gU91hPN!3X
z!JwKnX_6`_DFGPW^V7=eO%M);iN)e{M#5zJa%c?4vE!PSh>Zxu6A99@`{8n0q`2LL
z!(mL*>;|$diO1v0w(X?!4?Q5Mncts7AP}H$zZ`0>d`)98%C}8Xnu6^(94;bpo5uQU
z3>YwgP-_Uk-;ZtED5bD%TR9vKNlkUr+gGEP2NV?*5sgMc8Khd8^=n=ykuY$2ymTZq
z73Hrma&Ruut~l{{jM1Y<6Ap(_O5yYQICAt0-F-=s&d|b^JTUC
zrJ>s6atx`t@n8h7&jJh-8bOZz>j-abd7W%mE(bpTlo6vwF*)6fLer;DU+y*EXW6n9
zELyaP($Z2u2!+~s`kA?;Ij(T_@N-CK!kkf*n@CGB=lyMe-F8bUrA5o+Y=73UH@3b;
zn+hAN-!3OToJnU_l;-AU+-?t%XoOUchjr`LF@OGilv4cTz#(4z)z5kP7yWtdcT2c@
z@jF^uqIf(GHSF;$0KX+76Z#Cusw)4>@0}egsyD9vtC7`}%_oQdNp^NN*REZot*s58
z&qscKJ}D_FBoc8}tXxgio_E;y{w&4}>(8kZ^_ZrC2Dy6u0ecR93vfXJ`!;O;(@)Gi
z9sgt5dPl!RjvPF6P-SFf5Q#)cO-;qJEMl=3E|-gjhVOWG;q&y%_=ba9HLJ|svBp#2;lTS{Nogcg@BJFbL=5aZ_cYz%Lc#iDd
zHcRG~^pm{2@5de=`h);md$Q#)db60?`>oC
z>NNnEW_KOmymgyZ>rOFn=#M#n?hJl^j
zB`+_Zg2x_X{=9{hmX_l4Wg#MnfXn4VYmI4|;&!L}-v&x+EkLZgx|;lgeAV)x#Sjr(
zE*DKrO%xUmr>LliDN~-p?M~sd&koVv-j3E9!!WwR4TJA_z3O`14S?`NxqE!jz#OO3
zxiJ=tnaPIjeOr^8nudX`HBP4!hr@x^8n@d`G#ZsiBx3dPr8IU#5{skJL_P56@$~t8
zj^dIc=k&?XNJmFhb#--e=FAydS{^WD$Y7>Uol1TEEvl-jsI07{fB*g%hCy9j9i^qu
zv0!#4t9~;+y1%McFI#(xj!2yU0t8na+zMpPhyVZp8FWQhbW?9;ba!ELWdK2BZ(?O2
dNo`?gWm08fWO;GPWjp`?002ovPDHLkV1kacZ3O@T
literal 0
HcmV?d00001
diff --git a/Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/category_representant_random.png b/Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/category_representant_random.png
new file mode 100644
index 0000000000000000000000000000000000000000..dfa69846f1ac23710acb0acb35b24c95f75a4dca
GIT binary patch
literal 3171
zcmV-p44m_cP)Zm7K~#9!)tYH+T-SBSe{Y=`E+U7!M3I#!$|faR-l*7CWZ4Q_2tf=7
z4xpk%i^6pQAwXf&A8MzS1EdgCBW+{ZfdaU$n-+3l8LE;dl9R|{B@3-~snjk~9C4Aj
z%#a*%_I=*c4}LRzGa|*ITq7ufiy7W`-kbA3=YN)a?}Pv6f5PwJx#sU0fKc>ZD4JjF
znP!Qf|EB!HZcX4
zEIlTP;_}5T5lLry1VJzaFnzJ)Z)H)?zjv(n5TF$e-5SM!76o9pvJ5D1f8&Ww4du@7
zIAy6@m82)WilE8r##BnvulQn#-+ceX0O@v**a3)^@{WIf>FfVk
zp(@{9NYSLGlhSlDx=v1SQ4kOoAfzmcNY=$NMMjatl0B2iYS(*xvwyeuLjNfs2Ba*H
z7=S6*mH*zRt~HM})gG5bVTJu6hG`PZWXb9V8Qnk>1YC+lRolZjs%u!*+J>v94q29P
zHLpUhSXKa75CkIqS5Z}!a+eF=#ghPd&z~$A$R*$G-~90O^#ec{NLbV|a(tKPQ{FU9
zVi}EaI)f^S)U|g|@$e%oYi*-`Z6{@AWmHyHq9_Wgs^;l3ADtGOOV0WU4&K6h;UvBb
z3j<1KH7-rg{@};w`#%N(IS@I{J3fAS%YP}7*qyr}qw55cX;gO|%OBfF)6>t>wyulH
z%1Xo{4lhOF#pb*hPBMJtKL`yC6wGUe!E`*u&-?Ct`_$O<6(9&CB|!es?{`02<8u79
zjd%FtY1&`cwO$n_FppZX0!7j}x01B^8{_$5_@d
zaLH2Y?70836$@DrkSbJVQ|=W|$=20%oxOYa^2Qr)aQgIV5{U$5Wo4{fxsux2TKs-Ln>TN!r>AG>o@ndH
z1Cj&*NfcWwgr9A0
zEEe|`Ws1z~@a=nOaz83*nuZ_w3vQr0aS!IOLa9uzy>CecW(ZIDFbtz4FTC=~D>O7TAW0JGbh_aB@bEB0Lqq7gjwDI6w6v7u
zRY4G#zWP4}luBzl(R9{twGmmskOAZBRN!KpyD~56kR?L>SBbZ^Q(j)aXrMj$7WAb_f>bar;q(b2J}
zS4C08G)<;#^oeD%1e2LtRs~MwJRn+J%7)UJ&vL>}S;9NePtZ4UPb`#Lb-i9MpMU;2
zy}e(sv%9;SojZ5l*9bYvilWH$^-Bd_@yAn)M-vyVCN60QU;^4uAo}TCAWKMsK(O}=
zfk0r%twTH>=iPVT#pCgi&1PwBZDsfF-38t1eD~VvbLYq}3h3jDB{?)O`k4iwzyk)5
z-E;2dSv!rYoGK$1P7w$M$Ye50s-9=ho@I1&6tCBdBuVVtxs&?(`jYOIB#D@JjNrhH
zJb=kql0;Vb0C8*N7Byzh13HlQMiU>|X+$(c@@6kyuXjma=nN26{e4(=@{2aLGzIolau0
z7@{b0=FFLr<46=m64O3{x31^c(=&-QS>2dCad+~f1t7l~!|EyWtw#S$IJKpGg{~t)r
zPUmGt!!a&;Xa4Cvp1m9d^>eg+1`@KRENx8Qqw+7dLHUgy{<>nVFd>xg8FN
z!)Tf|?{!(0$;P8x{mI(}hUoK$7>^`+1_IIB*6u^Jm^ur2V9tf%uvuH?7+&M9eA(XQ
zP4-?dIFKZXzK`A~GIT3H
zKNg8|Hyoe(*|nj+w|GBoS$|#t3vKR7*23BS-nOs(a7AU=AK3+>Y8k8lxHTKO0Zdo`BDTy^
zng?>ipAAi1_{OTHN6Hj=Ro)YN7T=A_$Sv)-Dk}>-VFyuFRYh%WZ9$=Oxm-w+gzwTh
zh7bN*p7TjfXE+#TC=fkxYTSRy;{A+OyfX9cOfLo?4?;7Hfv$$?Z%U$AZU-@W;|kO^
zpf0OMQ4};yBb&{l>v}BswMx)_$_Vk8E_qH4eK@e~lSw_#FL^n;8#%7i+TZXEtNRosg2#BJH
zBuRP7M5ZRW_LJR&2d>+;3{CoH!uS&@&qvpW-m?^+vT}Z+IBhvET_aAXGY>=*MbeQFLx(=$_P)Jj!@+|6&ii>RZZ*v_>s0f
z%N%OQgB&MC(i!^vVLY?p{lC6Fe%O{SXKfXCQRPda&^=TF^gE$g_^@Z}$hx{Jv!UG8
zU8>?4U1uZ|#sLk>LE8~=`{DYhm=RD!Gc8J}ZR@OiK(!;HP+UBnO
z_Ix+wPItnoEMt*)d@7#&?@w-w{LJEcz_NPo)FrbNuPsP?OYL-FLf;R_rG>E-1&Vg4lG%{ZpNlFD>iJNyW`TDok!Q~yRdQp=>rE2
z96NUG(CKqW&Rsim=FFu_m#$p7a^m{a>({Sed-(eCF!OZzQ_8WaRr0zbHf
z*a)Ql`|lSS;Bn?n!s=bC)gq4lW4v%xU)RUkb@vH2Wy@AE3wiNGrtFRJ*+p%xT0S=;
z<2B;fe79ojb*y4Z``fa3P1A03iyqnU^A593SU%zBpXY3Ic5iO{#&_V`JS3j3^
HP6Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01ejw01ejxLMWSf00007bV*G`2ipS!
z3l;$J^~pp400TuyL_t(I%UzRCXdGo2#(&?;>}F>Zn@u)xlZuJSrcG;1OtNW0TWqTc
zBH~r3Ac_?%C5RYBj21*iFjml0$jyTk#9I-nHd5*#E#!~THZ77gA(q5sySqvD-|WnM
z-+UfoWA!;bhllrt_kDhX|7mHcvqy!k(}u+h+EYycB5bZ}r7s}$M90+an-Av2eKX(H
z6{c2?n-TkD?NdjpqMb>@YKQ|MGg-=i+zGa?Ou5RhoM($OUGwwa?tsfDPFS^0=C_BE
z$=>+0Pur9?(WOnaU)k9biXf`%AQ~exdD$u5S(;mDxq1AhA5a#6UC5lPYHjJQ?d!Mi
zO-+$?3bfYm!L&>Ol-y<|w?I6)hq}I$?Kys5>vAv#w?>RBJ)LdJuwIQl(QP|7uH!a8
zM*Hw6%jqI+wuGB4v79c_K0J!s)QWTCI(6MWQD1~#|F!R6tNBXP-cMu6j-!_J4L_Hq
z<F2|0q$d%8HUxh;9&r`y
z{#q){%65?^Km-~M2&aM@2n?x=jbbiOpg_4ktFBM)*q0=RhA2$WP?(+}F*wMRUyQNp
zNtEjoC@AIf$iP@PpWl;c4{1FRwM;`f6}rDVN8pw0{oY%JvOE>5wjSJX&K{Qz;_?g+TB2Tmu?`HcW^_xm&0d3%)<`
z&f4s|7C`fAa%4HNG*FgKU!uy6S~>u&Ao%Byh5^DvYJ-ifa=GHkxwdrjeVF|hrU_D^
z^+v`8;^i8nDr_63X^9twwS^qyY-q%O*{)0NO&LDVE>tF|G
nVXO-sT)+s%Kg-VDelY(xFG+}NBDldK00000NkvXXu0mjfol?Nt
literal 0
HcmV?d00001
diff --git a/Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/edit_s.png b/Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/edit_s.png
new file mode 100644
index 0000000000000000000000000000000000000000..e4951d22fc50853cdd310b37eb7f521c871f2f3e
GIT binary patch
literal 585
zcmV-P0=E5$P)5$5IjWG-l~n(3PJ;F>{S$UG2p?wMZ_8{c-wZn)q}^L
z?ZKjm7r`1UR=n7Vptqt3HuR91-JG(hgY!IWJG$9M9}L6%`F-==Z)Pn1#7W1s-|+t^
zRwgE2#AY4W7Oi!xDWyayB|#8~Qc4`x7RR;EZ0UA%f_&e{^E|w!N3+?)Z~45d)p+*&
zDUFQ=*RDXap^SXd$;hN2}E$wJSwqqe1!NC4eeGA_mZcpb-H!VFIL6
zyLtTNAwdw(Znw?;7(mOW7=aLlh%hviXKn2($z+oBTmgWyWy)Pk5UtT#BRZVx>+K_x
z$&j8aFi?TP3!?z{6I}ra2#9F2_RBrOKm~Sw8s*2zYr1%#!{oy{Onke!FCt#81901N
zT)PA;bb^i#pWxtuLtVw6_nxM7cgacs3pcLciao5E*(n2nsCdt@^L+Vv6j-v1iHC7H#jOFSg
zh2mHQP_Kt>sr8TaWCvph7{G_x+eiizzLMeg=q#zK5Mpa7?yg*Be5LE~$^Z_24mo}mi
z1=12Kf)G;s(85c>t)0|sZ+7c=y}PqB=X^ZurQReJ;xCP6bY|xKzyEhV!kZ94fsX{#(-H)MCP^Y9f=G`?Rq@^r@6Nev5jY?KCV`^^
zf`O&)0p!Gq6P<;HgZ@Z=ao-o|5hD%QUyQ+1S{mT3u&jW0TfSi#?glTe)ZiR}zS|mX(zi&YwTe
z`)_$4)0HxvR-1CU%*6OOGnFmsjRtWNkM69x+Y`g*D_w+$aQN_HYPA}bnHf(0>ICIV
zg<92&}Fo*XC;=Nz=0+1TltAn>3n#t5b#`)weH@_ePpjcawbIvq+A6FBEE#$09j
zpxOrn&Wf<@4KKGX>Cm9sPcP}ESER~ZAgrjT0gM-mBuPRppCgq{?J5Q^M!0-=o2U~F
z2~>-iL)Ob1wjKPJk-YLhz-9N@tt_tTDJ!Z09P$WWXd
z!#h8$<}eJnRJ$~iMfY#CqOGT(0Ni9@(Scu1d$Da4hhpiKdX8K>jK|0y*7Jq0E-UslYz1S=)!Wf$-$*1e(?S8
zp&}%WCXYXUoWH;FH)d{{Mno`}z5+<4LrmHXJ5T_KLg0D?wl9_^TM6H&ces6NiDQra
z2Cr+{U{H=el}@vNagnFao@M#tALIDX
zf5ydE*Lm#ZWBhsTIi_x&WGXvNr_)73K?S_^I17nUY|#*B`au`HdLBek#JBIek4Jv;
zFw>=Jo;mXee*DD4yfM2)<@Pd352pM3M>@9;wD
z6{bEhOB^X}jqzzg0O8FMxf|-iggDn5nKCpyw8j+kS+B7Fjb{5V&N-zVLM|h;e>3vQkc+n&WVbU
z5_rwS@4RQCxR+cuPpMSmg_mBu@?^35*z!}L^Iwy8UF*u^H1_}i02y>eSaefwW^{L9
ma%BKPWN%_+AW3auXJt}lVPtu6$z?nM0000Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2igP&
z6e1vy)n?QH00tCEL_t(Y$6b_LY+Pp%$A9ykvuF40?pd$B>)MIyTu9o)ZQYb0rw9S9
z5aQB{Kvk;(p#oLF6QVCjT+|mHs01pP2Y3P@DujY6iYRKUNJu~m2qX%k4NlS|&BaM<
zCthc7-u2$T86I}+Rvqc+e9|}nng7iEzY&1_M?TMv-E)i;3S_e}VJd}l0nRxPhjR`W
z1c*391VjKZRm^PkDW*!l->2PfQ>|86zIc*w-@;LL?3$xERv?at!9^TqpaxEa<>i(A
zh
z@P6>snVFqOCQ1{;aZC_~^m_wZtrn}R*Be(ZUph8XEhgErbNhiGVFqHL
zo?f?0n2FK^VE_hdMytKK*AKdXdH<2ayMi#F)9tgm-lo3Mqc>1Y98oGHmyMV%M=F&fxMSf#!Y~{%Z?`8po%Y`k&Cl&|&au4KQc<7Ns>HClK=4O#l=Q(qWsS-ErdZ30D_v)
zY&O4n&-}r?m~myf%F=2B-|z6`!+ZGh6QAInwz9Ut*MIyfm3oK8w<_GRuS}_2Vs>`s
z+s$Ueu%8!r~9Ha0nTxq>k4_w_R`^S;CH<@oXAL{UV!
zTqemy!BkQ2
z0a#p)dHktg@`GdN_{b+8->zbEJjT>x>S?q(tk>E&5z3{B&ulcCu^>3-1Q8)h1rG#H
zs5RQO+8uNRRIiNRx+iZ0)RSJa!GrI@C0jyVR
z=`e6POzHLdL-y}TqUurgJa+#Sdv?##>2&$Vv&U&|4g;Ec%shj^0Phv&gvyQ85@v*E
zMx0I$R839Q2{sH22!_J|sIQ*lk%vDAz#sl}hNaaO;@r^Bz}XhvAwJILx`q*|Dw#~=
z8_kVtYBrmW0!($g&pN_2*Dq47R;kq+{O9xv>OHa*Qw#;-C_v0;cRFNqxg}F2)Zy}>
z-fX>!>d|5nBN(cF2p%OVPT$2BzxFIiQsAbaMV!MiT8JaZVm^nOvR+vSvlFTwXKENm
zCLJAXZnTL)$5c7LJ=iT7&L5oR&oBOjSAO$7KKtOI(Qy6tUofW2IZ$Q!+RDEsCnwLF
z8cuZpI-r=(ymDoA?Sh%IduD>ns8w4E*+1DN3<21LF3aBcr%`TeS!Owp2
zD}Mdr>#S4_0kUz51A8Z#DkT8?@6_3)IOu#T3VL<4gZ10ULyvxiR4T%`5W}H3ccYp5
z&aFFVo-P#&h!gq)rQYb!?RyL%ib9fn%vcg5&M_ExPQ7{IQd(*s&!sspc*Q*Gdjtm#
z%mIdgh;<{^Th123o3Guh)&E^-a&J0{#^OvwE*nuuV#W(Gg?xr|6ym*dZDoy%=U@MM
z&R=*cw(D!wtpp;0nGV$VH<3?2@)#y5oC{J;+XWFB1JXcfhO76-KGbuQ4`i}qhf=Ai
z?3|0d_qA@XbJe$3PUM5y?=wMnZKUP_&^5EV1=)sr-wy*(j2@Yiqw%I^GNo&nwe|6*_0Adu}>X?GY#<
zaa?dp(2jN5Y(Gq&&tX2m6y^NM#{K^H0-1DXg+|7=i+kKRq>Mbv+53m
z2R%RKoH#7m1q|bz*{{i?OL))XW}wV5!ZtTJkzJ7+Qx4G
z8ZW|f@c6S?%M`m7eV$ztIr+brzWL4XwGwR~3(iS2XU^g{Twu9+6<6f6PDY*6O}V$v
zPgddFwNBq~>6dENUvd0>S4w3ilD%uT*yl4Y%XGTE?f)K^LK)|2PqP_cU!471^0SS-
j%9{5!lUJ>p{eyksiS5B
diff --git a/Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/infos.png b/Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/infos.png
new file mode 100644
index 0000000000000000000000000000000000000000..dc8c8a457c72892e7ca4ccd2dbedc3767e4ffbd7
GIT binary patch
literal 2250
zcmV;*2sQVKP)LX}OjmAcz@<)@>_$an&DQc<|x-Ba&L0Ig=T_^?0K4xcj
z-oNV~+}Zx-H#0jkD^&jINp60Vd+z=HzTbP!J?Gpz@S%Jtw}dnT4+HxEX=^>IZ~d(d
ze76I1q1K~F-ZJuViNNy_Y5#w(`r$Exx3?SOR$`3cC+Aa6s&%pHp4lv!-;9)L_Wt%L
z&m6os+WVdb?){($6a+u9#^muYFXf9HRsa&29D?*Pk)eK0pFYjg2QKlG=PutA65@Xa
zziUeykL}n9$$n(yZDj0SNJRh(DJ7TtlY}B^EGgOYoo-$~7rCJ%^s$1URO{l%zHO{q
zvk0sI7;@k^B(8y#P%aKa2m)Rmk4s}XZt=P0
z$vPT>hEv^9PR7d?D*EN_|e|Zk?zhjAwrQ9
zAGys>z?=Q4>IwrX1#_GI{O(X+zWuPL6j#yYvq
zHJg8$qw4%um@nPaK)|b^Ywt&GAp}(cokUV1kQ_T7$!Cc@V{xGz^F6VB6+v$l8Sc)X
zOuQ386iz9zgheuy8>LJ`W5#4J8&(!{rS@_OGy>c09c`^mJoJSQWN4J=rhB;1d!eAZ
zyEjTAl|Rf@1q|wgCg0vVEuZ=aYg*;cR<
z$SH4kKDZ1ybhdabOGiOkENZRFQ7yPVfXAg_>Z6xkHRB9goBd^5K`Z1wQycuOT{#`%
z?-gJDL_f#`?Q?=Tx`neU2>5jLA_RmGxJ|*XjZOK~+lvuscNS}#*R>&|7Xhod1yUif
z60BP>HAl5-K@}dCR`eB#q{a9ulj)7#d{$Urj6lwStqjo=ubg9QhHe!zlu!sv+dsIk*@nb
zQHv!h$pV=`P~p>=)9f#qfT5yKmiug4+XnG#<)1Ewdw6JVEw7%cA(52azp{=QjUI$3
z?c5}Upu%S`tI5aRi>vwl;r@~cbT~U#FKa<2-YK7e5dfjHXV)EE8weBhrSZD;vR_l_
z*IBh7hd_qJvrZSv3Q>*Y-PF|vA<{y@c;&bgWNK5^pfg)
zIbrl-ZfV*^0Ymow0?>0T@Yl|_k2mS&q%(*=X8r;1k$c7d5Os;cNTWR2RYb9saqBUSza&0h4-%yIn
zeF-|x4Dp+n-{bfj!-b}70M4qz{tyt&5NHBk0wxxW2rWL=bOf2z(Hcie
zNh&Rg#x0}-OF}$pjetLYAf2uE1Mv65ud!891kIr=zNc)n*+4`qeXJ
zBasjaxTZ*C!m6$kMrMChsNVr#t||a$0M%-4le(BKCiWYGb1EF3w%yGq6|j^79#Mcp
zHX<=#7)Ss~p#a!hhD63XZnaM`7V+D%p;yiEIEt)HcoMd!wCOC{6ZK5n2n?&=5!Eu5
zhyrm1K9PB`{bP0j88R-Lo4IY^Grx74UblfY@>IK~190a1Db*6{X$PNBz+*OjrdUhc
zS4cR(+xs(7Dzn)$`^BxmI9K1W0n{Cquxw*SGAi%?{Tf#w<2I|rZNxI<0pw^YRXFN!
zk*^-N5yA#e+U8r11ya=?x??;Fn6!bkKP|`n9FQfSHS+uxw$&950@BgvB$97Dg#bI{
Yzw9Cef0p>}RsaA107*qoM6N<$f?>Kfg8%>k
literal 0
HcmV?d00001
diff --git a/Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/minus.gif b/Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/minus.gif
new file mode 100644
index 0000000000000000000000000000000000000000..154e45a5ee2baa0bd114ee01417a3c595e13a7b4
GIT binary patch
literal 87
zcmZ?wbhEHb6lM@+n8?iV|NsAnh6V-(hIjAYDgI<(WME)s&;fFRvce1uOd50gSDt>$
rpUk}_OuXTqLc+dE;T4@eYD+S|Pkc6Mr|u7}Yr0Q=o%`<0$Y2cs-bNsJ
literal 0
HcmV?d00001
diff --git a/Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/next.png b/Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/next.png
new file mode 100644
index 0000000000000000000000000000000000000000..32587c4eb9984a729d5f0318ac2c12e6dcb61072
GIT binary patch
literal 348
zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6T^Rm@
z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPgg47It1OM)pZ5wLl@s64!_l=ltB<
z)VvY~=c3falGGH1^30M91$R&1fbd2>aiF5@o-U3d7N^hlZ{$7Xz~dU9&~%4mVzt?V
zrZzoo2XW5MS(*_IA|6vZ7#A#R5!{f+e29fZs$-G2o~720sj2_}=Nw)yx|7#4g=5Kq
zLy~J7_D0!OGEO=n5>c)*cjeVRY!h7E4k&*3v@yz->5JCcE2S&1o?zD48|rZF$rp!B
zY7ODK(_0vCiLgv?nWxzBr@P=D%Z=KNJHLFhcP-Rkr)FlJaOva4n6-J?4dzdBl8PDS
k4jkajYe+TyBVWZBC}Z^Pl-PA6pcfcCUHx3vIVCg!06Ca@#Q*>R
literal 0
HcmV?d00001
diff --git a/Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/page_end.png b/Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/page_end.png
new file mode 100644
index 0000000000000000000000000000000000000000..c8f54fb919a106efbda7efc3896fb5be03bfd8a0
GIT binary patch
literal 536
zcmV+z0_XjSP)P*DMoq#*3HX#RY^SdIdxGYjiHtvw--f=I`N
z+8_md*!s@Z`Ed^^nWU?;WA-+d0LFm}pqnU3ON*U?iTBgb`Lw&wO*cYHi3(({$q$A{
z)8G@XK2EnOty=>v;1^I|ntj2_c7sl+(Q*DZI6wH7fY)7JE8U(ffdxX~x9e+tdHyA<
zI}IWo_r~=e@TRK^vnFSqyF>E%?Q6DwoN(QVN`n`Dg#s7?Mu5k_-qhS8#u$#ita*d`
ztnw-_2229B{_IsU=acS!)nny*lhhn|tqi#EBpCvRfrr42n-;IOh!RSaJGyB9|LtGw
azmHp`TEWb5`!iXhTuXFK|x~>iJ(gt24BFXh_B#-
z_!ur-xf2YiD-}VQ5D0FD45DU+n9Iy$+O9sw#njx|bgCzATzH@sUH#YpojP@ce=y86
zVmqa=0u`Vl^cP6)s%6Gk`RUKx`57SD)$_W3a|zY{b&lRhHKt7lPQ3`TFPWk=TH>7Gn%cS8lO<
z|4|TP^UM#rBXeW=<3uNg)ypeEh&|4Hqu%6QtwAa3|BmcvjEEp295x%YcfT{cQ04Z+
zr@4?)1|R@8E>(veZ)*)&``zKUN(w4;c7L$>`gwNtO}~W?fg}qsz$`Eiobv~2V{WEQ
zYadh5Ih`nL#XAl7n&~bqJ&Nk5VB09ZfC`d(7)oj+WKNnpf^&Zaq{ZS(4
zMP{%*s_L`P1vqbh;7dF>?Z>VGS;4^ErGiWQB@&UWUdGx)ltTAJoTS7_imKB4<+Ak;
zMiB6()?l-~1IF_6>leCvJE$sAx$@UHs2wZUN$onYkasJbGz0b9brCq5W1v9CFZ8Ki
trxGv|NW}SV?N0mrnSgF$*Zq&F<2Pw!-MU?CE@%J%002ovPDHLkV1ieC06G8w
literal 0
HcmV?d00001
diff --git a/Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/permissions.png b/Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/permissions.png
new file mode 100644
index 0000000000000000000000000000000000000000..2ebc4f6f9663e32cad77d67ef93ab8843dfea3c0
GIT binary patch
literal 749
zcmVe|tv9>?g+k#9o0pTxd@;_sq{kwlU;^VvV*?BV8P@}BoaZTQUROpWV6|-M`|^n&)=+8tHo3*<<$NU
zU`%V~ZF;?hBSYsjJ6%JzV}E(D{pOLqQklliUf9um_tGl-wty`y*p?eYNW56P>X@1s
zZs7KrRZKtmV7Lqj^5Fgr7_`LjhdJK@ltF&O`j7?*NUM$KvmNGz)3WjM?V$vHlPT0AFyF?kLE<#HZabCSW3-oa*6;Z
zrXD`Ulwd<^2glP%1Y1Kc1Ij%DU^=ME(jKf6APNlA$Uu;J4bVilQHSWX5uJ$9Zsp4M
z0%!@LvyTxz=Z6stxlichODIY+yNGt%RM;m`>H4LOKLFs9Y%b5aUN|2|{0Zw|<_~i}
fmXz*V19AKYajLSDt>$
tpUk}_OuXTq!UNr$dn{e^8y4MN-g@gq%39AN{j|tS=f3~5*I;0<1^_HKAv6F0
literal 0
HcmV?d00001
diff --git a/Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/preferences.png b/Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/preferences.png
new file mode 100644
index 0000000000000000000000000000000000000000..30393347b7525e89c86db44ba4edc59a2d88f7ce
GIT binary patch
literal 714
zcmV;*0yX`KP)
z5EwY}YJoHW000SaNLh0L03N{r03N{s!)a7g00004XF*Lt006O%3;baP00076Nkl{K6n?uwEKIly1x5=F?}}|i*I1E|++1R8DDJMn#^%gfo4d+{3JVLnwY0cM
zLFkMa0@VeVAApCQi3#lCMJtoN!a|$zy=A~*9N1l6@>nwO&G&up&6{0=a}H6>=%3uh
zhl{?h3H#_azkhfxFD4?RPwWWYL68?3^0)Y?qCZ(mfQj!HC?sR(xdkx-_i(=)cMP>f
zn7{>)&U{q=c}WX5BmoCRsBIB~^kTMdVyA~T{?-D44^BL7i&in?6|7M^glYeqVFp
z>MuVbCS$JWxV9Y`{Yw$|S`N&gjSZI>A2K61A($!XNeR_R;NNaDxUke!FQ_ClV$&A6
zQ~~z=Sg7ate~mlUAfDo}pDBI1NJ$z7KF5XBXK)#rODQ>jM$#hGR<5
zTt*S%hTz9inpR|J1qi+&;`B13cTo;+|2}`StzJgT+0zn;>%YF>9CEY~
zL2seIMn4C=5dod$ny!L{3J|bI4k3mjX?g}~CsYC!1{7ldon=A^R&Vx4u=Qx`qnuPI
z6rf(O?}XzAA{}i7;!EVikDo9c4jFm5TxQ*Fmsyq-sWRQ2GL;;6`X`^yL#b4PR4N6X
zPA5*A=31>KC>D#*YPF!QL70(Y)*K0-AbW|YuPgg47It2F;V`M|%|Ic^64!_l=ltB<
z)VvY~=c3falGGH1^30M91$R&1fbd2>aiF3do-U3d7N^fn+{=5&K%`}V3+E%jHP<&Y
zikg%}GFqvqWGzcz3{nVGVr%G{)N^36xq?r_f<}$~DuS#rsdL}k%}@EUbvU>$j+1|*LJg}1efj#eKRqE~2E!4)+2;9sIG(&_zRBLOqe1XQ
zC4UMB!$>$j+1|*LJg}1{m?%yz<=a@W5j$$4hNGd^5;2{7>=?u{9qOk
zXZXk>F<)@iV}=k0HU}m&C^b^_Y+w;uu!SK)W_~s!6A!~H10A(n
THm|jSMl*Q2`njxgN@xNAP~?nrncbK0#;`47k%2_!Rs
zIxwV5#Zna1feEmRgn&SCD5CsG-Dc-Tq7gh!q8>H|6!L6ji{ILLzvi>ZG&oQrvVer8dlm0CDz_B0s
z?mI{h2MR=KL6I|CBwGiKT=f*fif1T7!eLjdPdm5
zeM`Tw>Pnnm9T(lqZZNQ
ze3W=;ZoYVHrR?we>qd{Jw2`kQ`q8&Hc2d-3IyzJ-LV%+8^sZvE#KJ{KuZ}U@v?ief
zxm%6*Q}@p;x4nMl3b7r12SK5;=E0bE;v+38$|hd?Lv>@0tMoFNr)U#LzC_Y3P{?z&>jt+I^||KCE|AY
zlnr6m?iwDrPi~KBu=?czE+kMz7Rh_}#8d|l1;C-RPv~1~f}`K$bO-GK`hs)-0000<
KMNUMnLSTaPupLqW
literal 0
HcmV?d00001
diff --git a/Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/uncheck.png b/Piwingo/piwigo-data/piwigo/admin/themes/clear/icon/uncheck.png
new file mode 100644
index 0000000000000000000000000000000000000000..2f7df3503e1d944a61b89f7c9e57175e38eb8206
GIT binary patch
literal 213
zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9Ea{HEjtmSN`?>!lvI6;>0X`wF
z+Zi~1{P=O`^tl=8;{HHE#*!evUQL70(Y)*K0-AbW|YuPgg?
zMt)HvqnXQY?*CBD!6<42E0#E%>ycw
y^mK6yskoJ#aDZt`*xICo0A60@c?_=^7#RYKxO~GWS!V(jF?hQAxvXCYoym;e7ACet8!=zvSpGimj8_NhC5eb7DJZodA5m9NP3
zv&H2xzwVn9+xpBk-n8idb-8{2>fb)hp0PxWnVH#|nYmey?`)YtZ-M@v>ff^-{`mTw
zC;MA$0ubytdf-69kpl+`IG?>)&i~%%%2IYC0|SE_#s&s5PUa3PmuYl2&VMU^_;|dJ
zfpcGM^$)4o&7zyq*nq$-C4bG$$|(;Y*T+p^aJZCn2xy9!?S~1;jxTSV+sdHY5vO`f(qyy~N|bmG)oFZdav+iFYxJh(6s=ywKBS3j3^
HP6ioh37r#ZwxaODgQ{!zin7?LV=S-eKtK
z`6{0isjPwY(x$Qo5*dnkQbD!f1=|v@wjLi@|2G4!vS!~c-tFcISBAx+g@uBNOhHFB
ztKz#@!jtC{2#-FiJa^`VFr#%)aq3R=R|8&>CduHCjZe+%Q5UE}xtE7Y4dhBHrlwMe
zet8AGn8MM$Yfv3PS6{k67Yp@;ej3oi+_wc&+hT+z%nED3c>=JZLCMRYdID6PgS#AB
zI3m?LInE|1o@zZlG94P+vj_mZX%uej+4wao&4Mqhf!ntZwgy;c9#o!zx)?$G&fUq9
zs^N2F#!={l?W2wjOom8KDF
zX!trYy@=4*By=U_C4X}D_*;5SL)^*>t80addbk8HIE%uz@+hxZHPe3N(*0#RQt~Au
ze+!4(-@M|a)jfcjT>B!<+C=25nSt+8v`p&hsDL3*$U`09%
zbdLP1Cmw&xHq#KR9Gn1G`R{a?ZHZcO@+0|QQ{DdN22(H8f!Spa;<1UdOeMsbQ1js!
a0Q>+PLX&jQI#L7x0000o%Ze?-`3S)9*
zVRU6=Aa`kWXdrZGWgtgMO;8{@Iv{9tbZ|N^FK20Oa4v6hXCwbuKmY&&21!IgR5*>5
zlRZl#Q51%sJ7!0WOwx!^&@EI5ehx!y5{5t+l{9uK#73)S3(2pru~JO4F4(0DnDY_pq1NP@m_n!`EIeYo5ULox|7Ik?Wj^(4#;n;V%NTwTKJ
zCA{X~YSgSTs5uSJCTypcmyOR;Q^qE2PlNLzi+!k;q34&&;+M-(hTc9@-wl|B)CqL&
zG8w7WYErA!RpfnxUE3%p;Qvbal~;Pc_@{n0=)yc9klc2PUgW|gN?ZB
zD${j|Mx#WdQB2n*?z(CXHs-+_3E6@3buh#EJjyVzEDOuBP=-M`pJyG+9XKBfS%BRY
zSXxXbG1F<3QbZyVB9RD6Da>@5#blBdSXzMHK@hbCXZBwUBNRd@_1{D(j8KShK93FN
z7MuaL)eJkJx)^F(Vc&1O?tt(H6$i&6zShCsm>fUydP7L3o?HWS$_N~wOu
zVliT|*qh!&Hp`rCW5M_;90G6z&o>~Cg@Ob@Ae~M}+U<7V=$}Em-Ih+LBS8?zW1%27
zAV=^FpuRyb3F_0JS2QBOfuA5>!3h0;i!OYzhJ40h`31cSeE;Ct!}ABk)6{E3K9Ohu
O0000
+
diff --git a/Piwingo/piwigo-data/piwigo/admin/themes/clear/images/cancelhover.svg b/Piwingo/piwigo-data/piwigo/admin/themes/clear/images/cancelhover.svg
new file mode 100644
index 0000000..bf07c77
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/themes/clear/images/cancelhover.svg
@@ -0,0 +1,6 @@
+
+
diff --git a/Piwingo/piwigo-data/piwigo/admin/themes/clear/images/external_active.png b/Piwingo/piwigo-data/piwigo/admin/themes/clear/images/external_active.png
new file mode 100644
index 0000000000000000000000000000000000000000..9bbccfa9677f4214ca9458267ef6bbd1fca690bc
GIT binary patch
literal 571
zcmV-B0>u4^P)3v5D-5w
zFl|y&jyXAZ2njKBjm08|`aY%e%gyCVONtZ}NDK@&5E4T+J$`$VB05IG)T%
zXW%6VCX3A>R_gwEzA}(T@^nr`1WFA>NH$L}L^vYQY_&Uu@V!|6tk%Dq?T&h**-}y4
zoo=sBL3zE^6iekdo@4R5Nhrw_Jhm0}>+|B`?R0dZ1_mE5
zKXF#m<%ino%+BE-AWR({NiZ;B85u$*FJFYq-vqzde%a{X-|TaBqAxIEBP3BVH)v^p
zs%_Kd2fo(;yw!i%=;!J3(A?^i!r5oF(PXvJWwp_?+v#f94+a1L00DGTPE!Ct=GbNc
z005FnL_t(|+8s+%0>e-MOJ}Py+F6}Co1Jaz{+HP6lAjQG!R-e_SOE<@KB%G&FB1f&
zv&C|aWC}=U0F_2(0KxtF{$e7``PBwI`PCZWNX%v7@qrBhlv=Adip%Y8e>k4bm+KA9
zR=d;f^#{UmG)9iki!}FeQMoFYHxk5?Q4+4i1??hHI
Qvj6}907*qoM6N<$g4*{0b^rhX
literal 0
HcmV?d00001
diff --git a/Piwingo/piwigo-data/piwigo/admin/themes/clear/images/missing_screenshot.png b/Piwingo/piwigo-data/piwigo/admin/themes/clear/images/missing_screenshot.png
new file mode 100644
index 0000000000000000000000000000000000000000..4c67f618d0903bdc70be092264aad007d986190c
GIT binary patch
literal 1684
zcmbVNi(ArHAE&(INSt|Drp;b26V!E4HTU
zSc;peh=|#%78KfWW-X^Cn-{Fenc)rbGPPjpe*FpW`<&&`3)t;C3+yp}`=@;Ql#aVw!{tMS*rcj5>K!1rV{w
z2#aBYK$bQiY!|5dmIDwpV`1@VGnEk(Z13Ne?3D|IK4GEBtdMWh(`gJAC?u0cWzo)j
zdXdgb`7{)Zk2-l}k39%vqQj#8O}wPizKjdo%iVu%MJIdfd9vsuSc9aH&gRS>}#nJCTC?M|qf
zaH_eaX4ekYtQ|1ZuiQCy>^HF_@z9qCA042k4)+ZPQ}~e5_UH7ph2`lBY__Pi6+hON
zP^H$5HAM;(+b_q*$=(UwryRdv{9f&sy4T)bBb<=F6FqtU_vM~_j*fr4cp(P(lbHkj
zqi5$IT`^M0F2JdXr^Cbl;T=Fq)-*#4@7FX_f;tR(4&YIB0)e1SCi^NYz*&)*$K&m3
zrN~t|Q9e~*FqlXt3l|sD8X6m6o}O5BH&^-KqK>t>6dy0=oT&Od!T-899FD`|@zw|I
zsaR1`t$et
z`}&%@yD4XfY9VkKc9kQSWzH0jD3y>+I-MTPWFDm=4ttgL*W;>u=r3g#D$Bm$>RC?5
z*aIxVze0IXlB=V$^Qf{ZvOf)(wR$@Q<_sr5*F57*#NMa-mUjEZ9#JyuCxu^mrXTYV+=`7__&fx+Q7e)u8f
zS$k7N%{dukCOn9`)kk&n@JLlQ;=7zCwd|XcNd6JGB+dN09k^H|8rjsT-LRgXp5b9(
zceLYNF4qMa_%SKJdcdP6io@Z2J*F8F48^&K7iMSQ4gKUUHfK*ihV*v+^%o0}_hUP;
zh4F6A+S}_>914Yk+A&xxSRpRVe?P~e(>#l;m8P~SLoW@)ir7zZC!~6j!7gCep*^$^m6w&eRbPAuItNW_k2I>m?U2L
z>kT+wcV7MAV%vsxQX`ZuKbkjQUte#Q$ztt4r})0`aCgV}`T42ZPhXpU8$z~|bJoLw
zf+caeTe=4aA0PepRX`1biQ)74yjwQZ0%~I7ajjN+E-j517k6{6+qo<>dt)&=D@)pX
z?=_TU3=|J$R36MMXuxoqR*1(NOBMXtI9_o&J2wu!-M%Iygv*iQ$h*
z;vH8>XB2s^b5p(7PIuvN`s0HHky5Gj*Jsa^w-8K+z0{aBotd|P+IXFfN5p5a;uhZ@
z54jl0<#PSa^PXU0Vgfe3IxXq{<(Ju4@@!sKF`wymlSm{w
zVBE0C%YR3uroyit6fc|X-UYM|{LN)xt42EoIN^RS`^?XICcg)hrwpqzxF=i!fzXlE
z2R`Q_UM^rB`x=kGUcYlNkcvOfU`TR;)b~>v_u@J`J7aq;2R1+}{d}r$5C}viWj1|R
zQQ?MNSy_Sk_>fXlTi99^+RcU!A8W@L^y@A4Jp)%yijnz3bIT7;=l_m7ow=ZSrJ^#h@s%jbV^&>?(XBmB@@F#xi3@vdoNa
z$X50+wi%3d8bX#KGnU`<{r>)i?|WVEa-HjX&-0vfp67n<`#mbaQo)x7~ZkwwS4nab7B5~U8*GZ9@;$R
zeA@su-tvhEP*k7*-JfbNDQbS(>>psn-G7Ab^8qZi3gKI~8;%|d5N(hQ5*5=Bj+d0Q
zHy4P!W`@{a9FG}x>Wdh5iu9a>+bkG!_M+)M-M<>VJoDnlc6uuJlezx{C3V
zo@%6vcoTDSzfqxvECqEtT<4ato8`(l)@K~fOrOc${)V>YX_`;Gy|VfoDf37Kx|&A-
zC1b>)xTa9;QK^O4)RgZLcxcz_Es^^(^(E
z@Z-MfWz1!JqjHlIO$mWzQ_k3Q2x%e!Oz#zeUyrACn7`tTqfN_^Y24x13B%HpZqLS~
zEb>2v#ttg`Z-yTbp}qnDg~b{^2==uQz2^s}kcj}z_axSUKgtdHiocvKmzpaoqD*~E
zr|B*v^N0QeIeOsKdj!_7NF5akFd&YdA07@q+kpvU|JgO+S+NY*WOhF_N9s@RSiM3X
ztltUpI0By@RVNGT>->P^sP{6KH(GY8XVX}bT_34}q}7t2Y6bUI}x+XvOD3&%E5mI)CpefLCIw
zIGtl7{yI2}N71?Z==nEyf1ZX&>^%E&0zXONotnsFeT#y$PB(KketzqBG4C3)k(|
z=<}9yP`*05tZmQ1qtwTW<#6$e7E;uAO^=}6AP%jaECcD6
ztA*pEKH(e2QcynN+#;(SrxW`#14<0*Yv;sAGqP4_dtt;KdmY$mLG=viF&_mw5aX!JLzVgy9AtHyqcABzpb9&?Ox3oHz)F^EoorU>i#q6iQro3seuX;0m8{SzqNm#
zlfLZAC>1djMS|cbQImM#pf=O#fPVt8W2I(6L^TeG
zEq1oE5gKxA@kj?G?&3zE!viFTgyv`_kwy<;$XEwEIYTqe9tCDpt?QAZ`yma^
zz*(?T{iavM|E#WX7U}8F=zyh~h2u((H@x&=`O@^@u+(h^;!IB?90z+MWLO1`d;sHz
z9gHO-LL3%9E(E1gYP~-YXpX(bMS~>!;uWojy(5&(-%o!YA{qIFh$XE_Iy%k=>p&Ig
zzq`?qH
zIk#CCy=W3-AsY1fBa&~d>VQ5ZaXBlCmh*{b*13ui54!ZC?Jid6{`o^&zE^ysCWcQ7
zNv{eA3jUq5phrHl;6Ca*u>0qpkM=@DY~X~cX1Q*;uXb%H4W
zik#?kNxUTw(`BIpD=yjV6fdH2?n-(MXTd1*vx2o|)*43>XpmsIZwxWeTND=$VQiwp
zVRpP)uKdAMMEP3`oGpYs+u+R&Z*k_uA?#Oa&TJkgM;bwI71VPSYOp%jr(2q)R>kx|
z-7vB0Ch-#$jYV}#Y?kuySdAlVqgM0&5KgN`a}Qtv72H;Ea;|8k(f<0sAZ^EbD@gM6
zJ)K_dQbjKBnAA?xdvM*U*$XS`nE0;(y%jj`ehec5!|ew(+{N!PuP!kv)U4|A!dvC+(SAEv~63fG4#C9;L4bn?_3mukX$C?St9D@p)z!^%?4Ee-y(-=Ui3
z@}K4AGkbN>?d@U;qwBaUJ(!m}vyVi48+g2sVAd0gI?L67h(1TE2U<5VrvjPj(qY25
zD=!K;5wMoeH4f~MGd0@ztK(XlHro#waT{$|>S@Nn*=Fy72NWYro!@_f*D!Mr81G6G
zHbT0N!0Zmx{^1VFD^1`uwY&{Hy=m_>f7E%tgyK1fF|gTwgPbe?q(iXYpld&m3DF9M
z*(HGn>Gk`i&R>TOVjq53vKDjK%MPb^I%=u=x5)Ol>*;*A(&=?g_;;ev2kDq0#fAJz
zijEW$$Q-xMZMchVJVqZ+P$+UN7cx2yGD9>LnacNInwUYX&SD>MS@(RkT^DI|A)Nko
zxv!o(b2wXM3oSF*8UCiUkN;%wV`E$kM%~vvnmC_%GUYsokH+K%mQB?OQr1j`y4FX}
zNMB{zk!
zknqX{>661nc7}Riv7M7uM=ccnYjwY4Ji$M#i`y2DgxA?X15MF8vfKl?a_)DVUDgUf}s1(Q_&<)a+%Dy
zcEfMu0te1t8VqD*yrJctbM;1Am)ZlW+wYdtuDS$>;D=Gcy7go8#7%wv(P3<>^u||Q
z9fNrdXoqZ-)Xf?B4?%fXG>RUp^tqf#%tk=%jprP1C);!dGvD556aU!Z$aee=%BD;R4pjN){xk&yZw6Ghs%pkcnut4uIvX-|i@nmn*sks?P4d|_hch+x-dRq#7PdJ>SDdG76U?_tU
z_X)fBEHXxf2jC{33|3QfY22%Kc-O3!^AH{L1D|t;f)j_S@QM>vYX=%&)CuL?t)fM=$(KND6WUQq}jE7w8Y%s;oMX@@&NTud;
zyQs6TY&tI5w?R`zV}#U859a=rTX#XGb54I>=c8jmRKH3H}_1IOon>VqdAwVP~1B5k2UVaqx!quc+mo=u6g^?on}+
zZJ(H<|I_fuB@TtNvWRHlDREmJS~`M%&MhJ8KX00RnQ`~k>~CO@+BZ<7)k1jw(`Cet
z4q`im2i0z~Qumu;fH|}Lk)iAAwZtjUqsn6XYbX7TB|7dV^Fv8s0qa#bMpP!fM`r7>
zYuuS^l9B$C90>5y2QQzTQ~S5bcuad6V9j@x`Nveq_zGX_;9KSIS*HI%Nb)0(T;tWF
zE(jHG8Qx5{?3VcKy$8%#6hghw#>VWyTN+MtMQh?-i2t_q?e&u1=RfhI@>C^5F#5o$
zyoL9*_70&n(ck;xYy_?}JnAz7P;wS$UI06!m59$Eln*1T!JM@9KKQ_Ru}2grVv3
zBk_&*Gu6|w_N%YUa$xe@?3Qu{R?75v><$0YVpaid%bLbIQA1`L;K{Pb22!S4#M~3j
zu7q?{K(0|AUxYZA@;1;)|;CD{Z8l1sZtN
z;w6_1z3ug7@_DO0srXR|0uAy)U7;QGK4Vd)3S_}6-}8U@i21VJ6%!_iE6CMy%Q`b0
zA=@)XX5l&iN|OI&T(lpFxckm_d&!4ppQOIkQ3TAg_$Z#}Y)!CKGOonYY+;51%HqVN
zl*2dzIcnsADwiJ0Pr5&GPH=QJtbpuBtne3)Oxz`RBK$twAGxp4)-77j=VGAFrvL-O
z&tk?MpW$eSB49fmU~xZv8hZJ4i!;=nWf_Y_f)Rn5y0mHbUuGa(`5D>h-xg@ESiq@y
zSrh{)YZX%~L-Pg_yBV`+^4Ee+B=rC)$#_aqHyYOq7;GUK%xlw0^UKsCgG4@>?N
zU_s)a!!$IH>L>Gs2v`03c}9m_mTNLMT7l&O?{Tlt{f`rnZ>5Q&S}PgN#U0_);3Wq2
zx@Aeu$KX^(_EQeL|5P)B#os>8P9@C9?#cVcNqTfl~uE9QGjmy5k*(
z*Xl6+ZUsNnI+nmDf@h>SrfE!+R^O9IQ2T~MaN&B8Li!{E?zAhp{<%mEwaJfMKAg3^
zVS!KL#;w(dM^Ej$m(SnMPT8npf~4P3X|&Q7NLiD@jNu)`{a=qq4v~)21j$EUWV2h^
zKA-Q(j}}WVaO`PV0vR?I?>qA9rSHWJJ4ItlUMFXpJbA2CJ(|~}@1|33Fwx=vgjJ!A
zg+;9B%l-L9^7va|-v?jXd~DgPTY7?u_H)Yp$$O-tZ(KPh5l=%KH5JY2#U^SO1*13QG7f(vUuvd$-CwDD8CEo
z*IrVH;WJZ1kj1PW`kjx1nFQ_c<rjizeT
zdCO(RcjN=UwG`&XS-zWLsK6ao{-}(N<6O!Q>}w9DZFW`wB=oP8bcuVcgIO=m8V!9r
z^vHnyWnDK+M+;I`6`ps!kd2O^?WO>yV>#}T18xE4kg<9v@f*J_;TU`klLs&{{t-Y1
zN129*w{gZzBC_`BikG=@;P}huFv;^>eC`lpcIHZmjk;UN^5J4}7(CN|`8HtA6R5E8
z&g`(Jt;)>CjiGy)sri~8__?_8w787+k$hkwT@qEW4hB>0God9&u*Bl1du&UF8pL4a
zQ^jeWwjiC0e{(f4byC8d9*#lXASluwU;`~!g9IoUC8+yfAm?Vn
zLHB}mwKG*f9wmm^zdeP_{J?Zzw)$`YsNA~`w-K=O9c?=DzdBoP2a0dkNDtD1e##n7
zfmbutXhf;Gna;!BpIf<#2C!7#o{W%q&4`n0@K+0AMyt18Y7mAYaHR&FALmj%xU#)5
z^KvY+^hS=lkv1QsQdafx)hY&tAHBASHXZz58@?3-;2!BLEBzaHGrK6H`N_~%&KPLH
zTP}-z;qDUmFk0b)dXRUBuuHhJ)&TO@Zqc^tci!TzsUnYK2U|Ipx=}Fsyo&M1|_cvIF{N6gF?dwP25x3sxH3!HhW7tjK
zYtJOUSd>uRsb+;Xh&AoxB*@)4h845HNns7XjqN31@Cuu2xjc^e;Ri)B-YD|;)_4GU
zb#2v!edT`?G&e&g2#ej7z*+Z`x8iQI(hX0{Z62yG_&L?V1^4NT)=FnyrciUXejQg~
z&SCts_JMJT{yq9;4H(qBlFIA<+B^&DDqSjc`CDkLIwnRHI9;?v9Skspus!Mn|7Kv+
z3`x~3hPy?#`mAnM6C3!r5_7*+*&myL>c(pSHxRQJgxoI53ieTxDi+ivUan{UC}p}h
z?agZLP4h`eJ^fXIYY$04@_it
z_T}D=jp{e_e8q6*n524mks9C>`Usq~UXuo#5DsWl6D#rtB^Ckc(W5y&XIG{~;fLLT
zW1GwUVP%|wWO)f#hv>@EegJo?y*`=idE;(snKB;qG8Hj$Rd>!v%|6
z+&A=<3pt=G=JGH^gXd70LQcxQ&w#|kH)cURSRvy%k85}t`Yxlq}*aLrRa_VroDY@2He@1lUq*+Cs$bK*=m(Y(PJYSX@2EJiWPhFb5-6q
z(m>Qq8M8`JGd}vyMn7?R@)qOp^yO{F^p`)Qo2R9zX~4NC6vJP?
zu%xr?W+a27={PLdFcS~m4<3Ld3s@@)LGw@D)qoKR0<$o{`Z3_K8SA&
z+*P0X9H)jNZEbz0JFQYAU`uMUu6X1n0McTzuPHA<#Gp$i)rdlV={Lz)By)ZG@fy;j6
z3k}&k!OsrL-;Cwr`^nGiZ2g2tH_2+M0}}AHkcgg7JuEv)$@v!2Ach5rEz&5
z%6JC&q6k~<-OJkrXTy;loQ17+c;nK$5WC`Yd}PJ1)cf!zshL}U&2O#e*7ZF{PKm}S
ziD%Izo>RSkU2^UzOkI935`l9d@DmTxa5Mb~R}XeZ@BYZw3BaSBNR3^D>Mp|2k274p
zH{elDUScR^jdE6(OFCA!KAAok4*2i`F-cWam}C{?rLB`qW#@6z-Ba6#(>u%e
qXA0JTHUSj=4-b3)@4Ehd@Kc`W(528s?pZny&rM64Yk2bq@&6A?FW-6q
literal 0
HcmV?d00001
diff --git a/Piwingo/piwigo-data/piwigo/admin/themes/clear/images/stripe-cat.png b/Piwingo/piwigo-data/piwigo/admin/themes/clear/images/stripe-cat.png
new file mode 100644
index 0000000000000000000000000000000000000000..126c888e0aec6dcdf8511576436f643717e3319c
GIT binary patch
literal 104
zcmeAS@N?(olHy`uVBq!ia0vp^tRT$61SFYwH*Nw_`kpS1AsjP(PdV~3IB+l@WR?B;
zeg$6^1N--#0`n&O++<_$bck1Z$-N*g?c;x^OU%=`1f!R^DtQ34GI+ZBxvX#h)z93_t-L5FaGNz{KRk$Y2csa$N)m
literal 0
HcmV?d00001
diff --git a/Piwingo/piwigo-data/piwigo/admin/themes/clear/index.php b/Piwingo/piwigo-data/piwigo/admin/themes/clear/index.php
new file mode 100644
index 0000000..c01bbd8
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/themes/clear/index.php
@@ -0,0 +1,15 @@
+
diff --git a/Piwingo/piwigo-data/piwigo/admin/themes/clear/mail-css.tpl b/Piwingo/piwigo-data/piwigo/admin/themes/clear/mail-css.tpl
new file mode 100644
index 0000000..cfe148b
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/themes/clear/mail-css.tpl
@@ -0,0 +1,19 @@
+{* $Id: mail-css.tpl 2526 2008-09-14 00:33:53Z vdigital $ *}
+/* Theme wipi mail css */
+
+body {ldelim} background-color:#111; color:#69c;}
+#the_page {ldelim} background: #111 url({$ROOT_URL}template/{$themeconf.template}/mail/text/html/images/mailbody-bg.png) repeat-y scroll left top;}
+#content {ldelim} background: transparent url({$ROOT_URL}template/{$themeconf.template}/mail/text/html/images/header-bg.png) no-repeat scroll left top;}
+#copyright {ldelim} background: transparent url({$ROOT_URL}template/{$themeconf.template}/mail/text/html/images/footer-bg.png) no-repeat scroll left bottom;
+color: #69c;}
+h2 {ldelim} background-color: #222;color:#eee;background-image: url({$ROOT_URL}template/{$themeconf.template}/themes/{$themeconf.theme}/images/tableh1_bg.png);}
+img {ldelim} margin: 16px; padding:15px;border:1px solid #eee; -moz-border-radius: 4px; border-radius: 4px 4px; }
+img:hover {ldelim} border:1px solid #69c; -moz-border-radius: 4px; border-radius: 4px 4px; }
+a {ldelim} color: #69c; background: transparent; }
+a:hover {ldelim} color: #f92; }
+a.PWG {ldelim} border: 0px; }
+a.PWG .P {ldelim} color : #f92; }
+a.PWG .W {ldelim} color : #aaa; }
+a.PWG .G {ldelim} color : #69c; }
+a.PWG:hover .P {ldelim} color : #69c; }
+a.PWG:hover .G {ldelim} color : #f92; }
diff --git a/Piwingo/piwigo-data/piwigo/admin/themes/clear/theme.css b/Piwingo/piwigo-data/piwigo/admin/themes/clear/theme.css
new file mode 100644
index 0000000..714e76e
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/themes/clear/theme.css
@@ -0,0 +1,977 @@
+/* generic colors - clear
+.gcText { color: #777777; } used for text
+.gcText2 { color: #777777; } used for table header
+.gcText3 { color: #555555; } used for tabs text
+.gcTextInput { color:#666666; } used for inputs
+.gcLink { color: #005E89; } used for link
+.gcLinkHover { color: #D54E21; } used for link
+.gcBgPage { background-color: #F9F9F9; } used for page background
+.gcBgTabSheet { background-color: #F1F1F1; } used inside tabsheet & menu
+.gcBgTableRow1 { background-color: #DDDDDD; } used in for tables rows background
+.gcBgTableRow2 { background-color: #EEEEEE; } used in tables rows & some widgets background
+.gcBgInput { background-color:#CCCCCC; } used for inputs
+.gcBorder { border-color: #AAAAAA; } used for borders
+.gcBorder2 { border-color: #666666; } used for widgets borders
+.gcBorderInput { border-color:#777777; } used for inputs
+*/
+/* text color */
+
+body, h3, dt, h2, .throw, .content, label , LEGEND {
+ color:#777;
+}
+
+th { color: #888; }
+INPUT, select, textarea { color:#666; background-color: #ccc; }
+option[disabled] { background-color: #ccc; }
+input[type="radio"], input[type="checkbox"] { background-color: transparent; }
+
+
+
+INPUT[type="text"], INPUT[type="file"] {
+ background-color: #ddd;
+}
+
+SELECT, TEXTAREA {
+ background-color: #ddd;
+}
+
+INPUT:focus, SELECT:focus, TEXTAREA:focus {
+ background-color: #eee;
+ color: #666;
+}
+
+INPUT, SELECT, TEXTAREA { border: 1px solid #999; }
+
+.showInfo { color:#999; }
+.showInfo:hover { color:#333; }
+
+
+#copyright { color:#777; margin:5px auto 0px 240px; text-align:center;
+padding-bottom: 15px; }
+.header_notes {
+ background: transparent url(../default/icon/note.png) no-repeat right top;
+ border: none;
+ min-height: 48px;
+ padding: 15px 60px 0 0;
+ right: 0;
+ width: 550px;
+ top: 70px;
+}
+html, body {
+ min-height: 100%;
+ height: 100%;
+ background-color: #fff;
+}
+
+/* #the_page { margin: 0; padding: 0; z-index: 1; top:0px; */
+/* padding-top: 0; min-height: 100%; width:100%; position:absolute; left:0px; } */
+h3, .throw, .row1 { background-color: #ddd; }
+.row2 { background-color:#eeeeee; }
+
+#content {
+ background: #fff;
+}
+
+.content h3 { font-size:20px; letter-spacing:-0.4px; margin:0 20px 12px 0;
+ text-align:center; background:none; border: 0; }
+.content h3 ~ h3{ margin-top: 40px; }
+.content h4 { color: #aaa; font-size:14px; text-align:center; padding:3px; margin-top: 0; margin-bottom: 10px;}
+
+.content dl, dd { margin:5px; }
+
+UL.thumbnails span.wrap2 {
+ background-color:transparent;
+}
+
+
+/* borders */
+fieldset {
+ border: none;
+}
+
+fieldset.with-border {
+ border: 2px solid #ddd;
+}
+
+
+TEXTAREA { cursor:text; font-size: 13px; }
+.tagSelection label { padding-right:12px; }
+.tagSelection LI.tagSelected {background-color:#dbe8f3;}
+.tagSelected LABEL {color:black;}
+
+ul.thumbnails input { color:#666; font-size:10px; margin:0; background-color:#bbb; text-align: center;}
+.throw { font-size: 120%; line-height: 26px; padding-top: 10px; font-weight: bold; }
+label { cursor:pointer }
+.menuLi { background: #F3F3F3; }
+.menuLi_hidden { background: #ccc !important; }
+a.Piwigo {
+ font-family: verdana, arial, helvetica, sans-serif !important;
+ font-size: 11px; font-weight: normal; letter-spacing: 0;
+ color : #0cc; text-decoration: none; border: 0; }
+a.Piwigo:hover span.Piwigo {
+ border-bottom: 1px solid #0cc;
+}
+TABLE.table2 { border: 2px solid #dddddd; }
+
+*, *:focus, *:active, input:active, a:active, input:focus, a:focus { outline: none; -moz-outline-width: 0px; }
+A{
+ color:#3A3A3A;
+}
+
+A:hover, A:active {
+ color: #ffa646;
+ cursor: pointer;
+}
+
+ul.actions, .content form#waiting {text-align:center;}
+
+/* jQuery tooltips */
+.ui-tooltip {
+ color: #000;
+ background-color: #eee;
+}
+.cluetip-outer { border-color:#999; color: #777; background-color: #eee; }
+.cluetip-title { background-color: #ddd; }
+/* jQuery ui resizable */
+.ui-resizable { position: relative; }
+.ui-wrapper { border: 0; }
+.ui-wrapper input, .ui-wrapper textarea { border: 0; }
+/* jQuery tiptip */
+#tiptip_holder a { color:#42B0FF; }
+
+/* Global handle styles */
+.ui-resizable-handle { position: absolute; display: none; font-size: 0.1px; }
+.ui-resizable .ui-resizable-handle { display: block; }
+body .ui-resizable-disabled .ui-resizable-handle { display: none; } /* use 'body' to make it more specific (css order) */
+body .ui-resizable-autohide .ui-resizable-handle { display: none; } /* use 'body' to make it more specific (css order) */
+
+#ui-datepicker-div {background-color: #f1f1f1; border:2px solid #aaa;}
+#ui-datepicker-div .ui-datepicker-title {color:black;}
+#ui-datepicker-div .ui-icon-circle-triangle-w {background: transparent url(icon/prev.png) no-repeat;}
+#ui-datepicker-div .ui-icon-circle-triangle-e {background: transparent url(icon/next.png) no-repeat;}
+#ui-datepicker-div .ui-datepicker-control, #ui-datepicker-div a {background-color: #FFFFFF !important;}
+#ui-datepicker-div A.ui-datepicker-prev, #ui-datepicker-div A.ui-datepicker-next {
+ background-color:transparent !important;
+}
+#ui-datepicker-div A.ui-datepicker-prev:hover,
+#ui-datepicker-div A.ui-datepicker-next:hover
+{
+ background-color:#eee !important;border:1px solid #aaa;
+}
+
+#ui-datepicker-div .ui-datepicker-control, #ui-datepicker-div a { background-color: #eee; color: #08f !important;}
+#ui-datepicker-div .ui-datepicker-days-row { background-color: #bbb;}
+#ui-datepicker-div .ui-datepicker-week-end-cell, #ui-datepicker-div .ui-datepicker-week-end-cell a { background-color: #ddd; color: #0cc; border-color: #bbb; border-top-color: #ddd; border-left-color: #ddd;}
+#ui-datepicker-div .ui-datepicker-title-row { background-color: #eee;}
+#ui-datepicker-div .ui-datepicker-title-row .ui-datepicker-week-end-cell a { color: #0cc;}
+#ui-datepicker-div a:hover { color: #0cc !important; background-color: #eee !important;}
+#ui-datepicker-div .ui-datepicker-header select { background-color:#bbb; color:#666; font-weight:normal;}
+#ui-datepicker-div .ui-datepicker-links { background-color:#ddd;}
+#ui-datepicker-div .ui-datepicker-header { background-color:#bbb;}
+#ui-datepicker-div .ui-datepicker-current-day { background-color: #eee !important; border-color: #bbb; border-top-color: #eee; border-left-color: #eee;}
+#ui-datepicker-div .ui-datepicker-days-cell { background-color:#bbb; border:1px solid #ddd; border-top-color: #bbb; border-left-color: #bbb;}
+img.ui-datepicker-trigger{margin:-2px 10px 1px -2px;}
+
+.ui-slider { background:#fff;border-radius:2px;border:none; }
+.ui-slider .ui-slider-range { background:#aaa;border-radius:2px; }
+
+.ui-slider .ui-slider-handle {
+ background-color: #ddd;
+ border: 1px solid #aaa;
+ border-radius: 3px;
+}
+
+INPUT[type="text"].large { width: 317px; }
+
+.bigbutton {background:none;margin-right:-5px; padding: 10px;height:auto;position:static;width:auto;text-align:right;}
+.bigtext {display:none;position:static;}
+.bigbutton input[type="submit"] {display:inline;position:static;height:auto;width:auto;font-size:18px;padding:10px;}
+
+
+/* hacks */
+* html[lang="en"] body .content h2 , *+html[lang="en"] body .content h2 { text-transform:capitalize; } /* IE */
+*+html .bigtext { left: 70px; }
+*+html .bigbutton input, * html .bigbutton input { left:0px; position:relative; top:-40px; }
+* html .bigtext { margin-right: 300px; }
+
+.themeBox {background-color:#fafafa; box-shadow: 0px 0px 5px #acacac;}
+.themeName {color:black;}
+.themeActions span {background-color: #ddd;}
+#themesContent H3 {border-bottom:1px solid #aaa;}
+.themeSelect {background-color: #fafafa;}
+.themeSelect.themeDefault {background-color: #ffd7ad;}
+
+#pluginsMenuSeparator {border:1px solid #555;}
+
+#pwgHead, #footer {
+ background-color: #333;
+ color: #ccc;
+}
+
+#pwgHead A, #footer A {color:#ccc;}
+#pwgHead A:hover, #footer A:hover {color:white;}
+
+.AlbumViewSelector {background: #fafafa;}
+.pluginName {color:#111;}
+.pluginBox.incompatible {border-color:#a00 !important;}
+
+.languageBox {background-color:#ddd;}
+.languageName {color:black;}
+.languageDefault {background-color:#dbe8f3;}
+
+UL.thumbnails li.rank-of-image {background-color: #ddd;}
+
+/* Batch Manager */
+#batchManagerGlobal .thumbnails .font-checkbox [class*="icon-check"]::before {
+ color:#999;
+}
+
+#batchManagerGlobal li.thumbSelected .font-checkbox [class*="icon-check"]::before {
+ color: white;
+ display: block;
+}
+
+#batchManagerGlobal UL.thumbnails li:hover .wrap2 {
+ background-color: transparent;
+ color: #999;
+}
+
+#batchManagerGlobal .thumbSelected { background-color:transparent !important }
+
+#batchManagerGlobal .thumbSelected .wrap2 {
+ background-color: transparent !important;
+}
+
+#batchManagerGlobal #selectedMessage {
+ color: #FFA646;
+ font-weight: bold;
+}
+
+#batchManagerGlobal #applyFilter,#batchManagerGlobal .addFilter-button,
+.buttonSecondary {
+ color: #3C3C3C;
+ background-color: #ececec;
+}
+
+.buttonSecondary:hover {
+ color: #3C3C3C;
+ background-color: #aaa;
+}
+
+#batchManagerGlobal #applyFilter:hover, #batchManagerGlobal .addFilter-button:hover {
+ color: #111;
+ background-color: #ff9b32 ;
+}
+
+#batchManagerGlobal .addFilter-button.highlight {
+ color: #3C3C3C;
+ background-color: #ffc17e;
+}
+
+#batchManagerGlobal .addFilter-button.highlight:hover {
+ background-color: #ff7700;
+ color: white;
+ text-decoration: none;
+}
+
+.slider-info {color:#ff7700;font-weight:bold;}
+
+.selectedComment {background-color:#C2F5C2;}
+
+#pwgMain {padding-left:0}
+
+.buttonLike i {
+ font-size:14px;
+}
+
+.buttonLike:disabled, input[type="submit"]:disabled, input[type="button"]:disabled, input[type="reset"]:disabled {
+ background: #ECECEC !important;
+ color: #D5D5D5 !important;
+ cursor: not-allowed;
+}
+
+.resetButton{
+ background-color:transparent;
+ color:#aaa;
+ font-weight:700;
+ border:none;
+ padding: 8px 15px;
+}
+
+#formCreateAlbum input[name="virtual_name"] {border: 1px solid #D5D5D5; transition: all 125ms ease-out;}
+#formCreateAlbum input[name="virtual_name"]:hover {border-color: #3C3C3C;}
+
+p.albumTitle img {margin-bottom:-3px;}
+
+.groups .GroupContainer,
+.groups .showCreateGroup,
+.groups .addGroupFormBlock{
+ font-size: 1.2em;
+ background-color:#fafafa;
+}
+
+.groups .Group-name>p,
+.addGroupForm .addGroupFormTitle{
+ color:#3c3c3c;
+ font-size: 1.2em;
+}
+
+.groups .GroupContainer,
+.groups .showCreateGroup,
+.groups .addGroupFormBlock{
+ box-shadow: 0px 2px 5px #00000024;
+}
+
+.groups #addGroupForm:hover #addGroup,
+.groups .addGroupFormTitle{
+ color:#3c3c3c;
+ text-decoration:none;
+}
+
+.groups #addGroup{
+ color:#777;
+}
+
+.groups .group_number_users{
+ color:#d5d5d5;
+}
+
+.addGroupLabel{
+ color:#3c3c3c;
+}
+
+.addUserButton:hover{
+ text-decoration:none;
+ color:#3c3c3c;
+ background-color:#f3f3f3;
+}
+
+.groups p.list_user{
+ color:#3c3c3c;
+}
+
+label>p.group_select {
+ color: #000;
+ background-color:#C2F5C2;
+}
+
+.groups input[type="text"]{
+ background-color:white;
+ border:1px solid #d5d5d5;
+}
+
+.groups .AddUser .icon-user-add::before{
+ background-color:#f3f3f3;
+ color:#e0e0e0;
+}
+
+
+/*Edit group name*/
+
+.groups .Group-name{
+ color:#3c3c3c;
+}
+
+.groups .Group-name .Group-name-container p:focus{
+ border:1px solid #3c3c3c!important;
+ background-color:white;
+}
+
+/*Add Group */
+
+.groups fieldset INPUT[type="text"]::placeholder{
+ color:#d5d5d5;
+}
+
+.groups button.submit{
+ background-color:#ffa744;
+ color:#3c3c3c;
+}
+
+.groups button.submit:hover{
+ background-color:#ff7700;
+}
+
+/*Group manager buttons*/
+
+.groups .manage-users,
+.groups .manage-permissions{
+ border:1px solid #e7e7e7;
+ background-color:transparent;
+}
+
+
+.groups .manage-users:hover,
+.groups .manage-permissions:hover{
+ background-color:#ffa744;
+ border:1px solid #ffa744;
+ cursor:pointer;
+}
+
+/*UserList Pop in*/
+
+
+.UserListPopInContainer{
+ background-color:white;
+ border-radius:10px;
+
+}
+
+#UserList .AddUserBlock button{
+ background-color:#ffa744;
+ color:#3c3c3c;
+}
+
+#UserList .AddUserBlock button:hover{
+ background-color:#ff7700;
+}
+
+#UserList .AddUserBlock input,
+#UserList .FilterUserBlock input{
+ background-color:white;
+}
+
+#UserList .AddUserBlock p,
+#UserList .FilterUserBlock{
+ color:#3c3c3c;
+}
+
+.UsersInGroupList span{
+ color:#d5d5d5;
+}
+
+.UsersInGroupList .icon-cancel:hover{
+ color:#ff7700;
+}
+
+.LinkUserManager{
+ color:#3c3c3c;
+}
+
+/* Activity Tab in user manager */
+
+.activity-date-selecter{
+ background-color: #f9f9f9;
+ color : #3C3C3C;
+ border: 2px solid #D3D3D3;
+}
+
+.activity-filter-container{
+ color: #777777;
+ background-color: #FFFFFF;
+}
+
+.selectize-control.user-selecter.single .selectize-input, .selectize-control.action-selecter.single .selectize-input{
+ border-color: #D3D3D3 !important;
+}
+
+/* Selection mode */
+
+.slider {
+ background-color: #e0e0e0;
+}
+
+.slider:before {
+ background-color: white;
+}
+
+.slider::after {
+ color: white;
+}
+
+input:checked + .slider {
+ background-color: #ffa646;
+}
+
+input:focus + .slider {
+ box-shadow: 0 0 1px #ffa646;
+}
+
+#selection-mode-block,
+.selection-mode {
+ background-color: #FAFAFA;
+ border-left:1px solid #e6e6e6;
+}
+
+.GroupBackgroudSelected{
+ background-color:#ffd7ad!important;
+}
+
+.OrangeIcon{
+ background-color:#f98100!important;
+ color:#ffe4c7!important;
+}
+
+.OrangeFont{
+ color:#ff7700!important;
+}
+
+/*Selection mode content*/
+
+.SelectionModeGroupList{
+ color:#a0a0a0;
+}
+
+#selection-mode-block button,
+#commentsSelection button{
+ border: 1px solid #e7e7e7;
+}
+
+
+#selection-mode-block button:hover,
+#commentsSelection button:hover {
+ background-color: #ffa744;
+ border: 1px solid #ffa744;
+}
+
+#ConfirmGroupAction{
+ color:#3c3c3c;
+}
+
+#ConfirmGroupAction p{
+ color: #777;
+}
+
+.ConfirmDeleteButton{
+ background-color: #ffa744;
+}
+
+/*Merge Options*/
+
+
+#MergeOptionsBlock p{
+ color: #777;
+}
+
+#MergeOptionsBlock a{
+ color:#3c3c3c;
+}
+
+/*Merge options Radio buttons*/
+
+.ConfirmMergeButton{
+ background-color: #ffa744;
+}
+
+.MergeOptionsContainer select{
+ background-color: white;
+ box-shadow: 0 0 2px #c5c5c5;
+}
+
+/*Group checkbox*/
+
+.groups .group-checkmark {
+ border:2px solid #ffa646;
+}
+
+.groups .Group-checkbox:hover input ~ .group-checkmark {
+ background-color: #ffa646;
+}
+
+.groups .Group-checkbox input:checked ~ .group-checkmark {
+ background-color: #ffa646;
+}
+
+
+/*Group manager buttons*/
+
+.groups .manage-users,
+.groups .manage-users:hover,
+.groups .manage-permissions,
+.groups .manage-permissions:hover{
+ color:#3c3c3c;
+}
+
+/*UserList Pop in*/
+
+.CloseUserList, .CloseAddAlbum, .CloseDeleteAlbum, .CloseRenameAlbum {
+ color:white;
+}
+
+#UserList .group-name-block p{
+ color:#3c3c3c;
+}
+
+.UsernameBlock{
+ background-color:#f9f9f9;
+}
+
+.UsernameBlock.success_message{
+ border:2px solid #c2f5c2;
+}
+
+.Tooltip p.TooltipText{
+
+ background-color:#f3f3f3;
+ color: #3c3c3c;
+ border:1px solid #3c3c3c;
+}
+
+.ValidationUserAssociated, .ValidationUserDissociated{
+ color:#00aa00 !important;
+ background-color:#c2f5c2;
+}
+
+.ValidationUserAssociated p, .ValidationUserDissociated p {
+ color:#00aa00 !important;
+}
+
+/*------*/
+
+.userSeparator {
+ visibility: hidden;
+}
+
+table.dataTable tr.even {
+ background-color: #ddd !important;
+}
+
+table.dataTable tr.even td.sorting_1 {
+ background-color: #ccc !important;
+ color:#333;
+}
+
+table.dataTable tr.odd {
+ background-color: #eee !important;
+}
+
+table.dataTable tr.odd td.sorting_1 {
+ background-color: #ddd !important;
+ color:#333;
+}
+
+table.dataTable thead th, table.dataTable.no-footer {
+ border-color: #ddd !important;
+}
+
+.dataTables_wrapper .dataTables_info {
+ color:#777 !important;
+}
+
+.userPropertiesContainer {border-color:#ddd;}
+.userPrefs {border-color:#ddd;}
+
+.big-progressbar {
+ background: #3C3C3C;
+}
+
+
+#watermarkPositionBox {
+ border:2px solid #ccc;
+ background-color:#e5e5e5;
+}
+
+#watermarkPositionBox label {
+ color:#444;
+}
+
+FORM#categoryOrdering p.albumTitle a { color: #5B5B5B; }
+FORM#categoryOrdering p.albumActions a { border-left:1px solid #D6D6D6; background-color: #E8E8E8;}
+FORM#categoryOrdering p.albumActions a:hover {background-color: #FFA844; color: #3A3A3A;}
+FORM#categoryOrdering p.albumActions .userSeparator {border: 1px solid #E1E1E1;}
+#addAlbumOpen, #autoOrderOpen {border: 1px solid #D6D6D6; color: #5B5B5B;}
+#addAlbumOpen:hover, #autoOrderOpen:hover {border: 1px solid #aaa; text-decoration: none;}
+.afterUploadActions a {color: #3C3C3C; font-weight: bold; background-color: #FFA646;}
+.afterUploadActions a:hover {text-decoration: none; background-color: #ff7700;}
+.afterUploadActions a.secondary_button {background-color: #ECECEC;}
+.afterUploadActions a.secondary_button:hover {background-color: #FFA646;}
+
+.font-checkbox:hover {color: #3C3C3C;}
+.font-checkbox.selected {color: #ffa646;}
+.font-checkbox:hover .icon-check-empty, .font-checkbox:hover .icon-check {color: #FF7700;}
+.font-checkbox .icon-check {color: #FFA646;}
+
+LEGEND {color: #3C3C3C;}
+a#showPermissions {color: #5B5B5B; border: 1px solid #D6D6D6; background-color: #FAFAFA;}
+a#showPermissions:hover {border-color: #A5A5A5;}
+.icon-plus.cboxElement {background-color: #F6F6F6;}
+.icon-plus.cboxElement:hover {background-color: #F2F2F2;}
+.selectize-control.single .selectize-input {border: 2px solid #FFA646!important; color: #3C3C3C;}
+.selectize-control.single .selectize-input:hover {border-color: #FAC17E!important;}
+.plupload_filelist {scrollbar-color: #CBCBCB #ffffff!important; background-color: #ffffff!important;}
+.plupload_filelist_footer {background-color: #F5F5F5!important;}
+li.plupload_delete a {background: url("images/cancel.svg")!important; background-size: cover!important;}
+li.plupload_delete a:hover {background: url("images/cancelhover.svg")!important; background-size: cover!important;}
+li.plupload_delete a span {background: #FFF;}
+li.plupload_delete a:hover span {background: #FFF;}
+li.plupload_delete a.remove-format:hover{color: #474747;}
+
+.addAlbumEmpty {color: #3C3C3C;}
+#permitAction p {background: #FFF;}
+#addAlbumForm input[name="category_name"] {border:none!important; margin-top: 5px!important;}
+#addAlbumForm input[name="category_name"]:focus {background-color: #DDDDDD;}
+.buttonSeparator {color: #3C3C3C;}
+#uploadForm li.plupload_droptext {background-color: #F5F5F5!important;}
+.addFilesButtonChanged {background-color: #E5E5E5;}
+
+.addFilesButtonChanged:hover {background-color: #BBB;}
+
+#checkActions a, .deleteDerivButtons a {background-color: #E8E8E8;}
+#filterList select, .pictureLevels select, #permitAction select, .sort-by select {background-color: #FFF; color: #4E4E4E; border: 2px solid #7070704f !important; outline: none !important;}
+#filter_category .selectize-input.items.full.has-options.has-items, #filter_tags .selectize-input.items.not-full.has-options,
+#filter_tags .selectize-input.items.not-full, #filter_search input, #action_move .selectize-input.items.full.has-options.has-items,
+#action_dissociate .selectize-input.items.full.has-options.has-items {
+ border: 2px solid #7070704f !important;
+ background: #FFF;
+ color: #3C3C3CBD;
+}
+#action_move a:last-child {background: #FFF; border: 1px solid #787777a6; box-shadow: none;}
+#forbidAction, .selectionEmptyBlock, .noFilter {background-color: #f3f3f3;}
+#action_title .large, #action_author .large {background-color: #FFF; color: #4E4E4E;}
+#filter_dimension .slider-choice, #filter_filesize .slider-choice {background-color: #EEE; color: #777;}
+#filter_dimension .slider-choice:hover, #filter_filesize .slider-choice:hover, .dimension-cancel:hover {
+ text-decoration: none; background-color: #ffa646 !important; color: initial;
+}
+#filterList .ui-slider .ui-slider-range {background: rgba(255,166,70, 0.9); margin-top: -1px; border: 1px solid #ffaf58;}
+#filterList .ui-widget-content {border: 1px solid #EEE; background: #DDD;}
+
+#batchManagerGlobal option[disabled] {background-color: #EEE;}
+.dimension-cancel {background-color: #F8F8F8 !important;}
+.pageNumberSelected {color: #FFF !important; font-weight: bold;}
+
+#batchManagerGlobal .ui-state-default, #batchManagerGlobal .ui-widget-content .ui-state-default,#batchManagerGlobal .ui-widget-header .ui-state-default {
+ border: 1px solid #ffaf58; background: #ffaf58;
+}
+#batchManagerGlobal .ui-state-hover,#batchManagerGlobal .ui-widget-content .ui-state-hover, #batchManagerGlobal .ui-widget-header .ui-state-hover {
+ background: #ffaf58;
+}
+#batchManagerGlobal .ui-state-focus, #batchManagerGlobal .ui-widget-content .ui-state-focus,#batchManagerGlobal .ui-widget-header .ui-state-focus {
+ border: 1px solid #ffaf58; background: #ffaf58;
+}
+#batchManagerGlobal .ui-state-active, #batchManagerGlobal .ui-widget-content .ui-state-active,#batchManagerGlobal .ui-widget-header .ui-state-active {
+ background: #ffaf58;
+}
+#batchManagerGlobal .ui-slider-range.ui-widget-header.ui-corner-all {border: 1px solid #ffaf58;}
+#batchManagerGlobal .font-checkbox.selected {color: #777;}
+
+/* Picture add */
+
+.upload-options, .upload-options-content, .options-open::after {
+ background-color: #f5f5f5;
+ color: #777777;
+}
+
+/* Category List */
+.categoryContainer {
+ margin: 0;
+}
+
+.categoryBox, .addAlbum{
+ background-color: #fafafa;
+ box-shadow: 0px 2px 5px #00000024;
+}
+
+.addAlbumHead p {
+ color: #3C3C3C;
+}
+
+.addAlbum form input {
+ background-color: white;
+ border: 1px solid #d5d5d5;
+}
+
+.albumTitle {
+ color: #3c3c3c;
+}
+
+.albumInfos {
+ color: #d5d5d5;
+}
+
+.albumActions a {
+ color: #848484;
+}
+
+.albumActions a:hover {
+ color: #FFA646;
+ text-decoration: none;
+}
+
+.albumActions > span {
+ color: #c6c6c6;
+}
+
+.icon-red {
+ background-color: #ffcfcf;
+ color: #ff5252;
+}
+
+.icon-yellow {
+ color: #ffa744;
+ background-color: #ffe9cf;
+}
+
+.icon-purple {
+ background-color: #e0daf4;
+ color: #896af3;
+}
+
+.icon-blue {
+ background-color: #cfebff;
+ color: #2883c3;
+}
+
+.icon-green {
+ background-color: #d6ffcf;
+ color: #6ece5e;
+}
+
+.icon-grey {
+ color: #444;
+ background-color: #ddd;
+}
+
+.applicationCard {
+ box-shadow: 0px 0px 4px 4px #DBDBDB;
+}
+
+.applicationCard .applicationName {
+ color: black;
+}
+
+.linked-albums-badge {
+ background: #DBDBDB;
+}
+
+.breadcrumb-item {
+ background-color: #fafafa;
+ box-shadow: 0px 2px #00000024;
+}
+.breadcrumb-item:hover {
+ background: #ffd7ad;
+}
+.breadcrumb-item .icon-cancel-circled:hover {
+ color: #ff7700;
+}
+
+.linkedAlbumPopInContainer {
+ background-color: white;
+}
+.AddIconTitle {
+ color: #000;
+}
+
+.search-result-item {
+ background-color: #fafafa;
+ box-shadow: 0px 2px #00000024;
+ color: #777;
+}
+
+.search-result-item .icon-plus-circled{
+ color: black;
+}
+
+.search-result-item .icon-plus-circled:hover{
+ color: #ff7700;
+}
+
+.breadcrumb-item.add-item.highlight {
+ background: #ffa646;
+ box-shadow: 0 2px #af7200;
+ color: white !important;
+}
+
+.move-cat-container:hover .badge-container i,
+.move-cat-container:hover .node-icon{
+ color: #ffd7ad;
+ background-color: #f98100;
+}
+
+.eiw .messages a {
+ background-color: #00529b;
+ color: #bde5f8;
+ padding: 2px 7px;
+}
+
+#wImg {background-color: #e5e5e5;}
+
+.cat-move-order-popin input[name=recursiveAutoOrder] {
+ background-color: #d9d9d9;
+}
+
+.cat-move-order-popin input[name=recursiveAutoOrder]:hover {
+ background-color: #ffc17e;
+}
+
+#whats_new_popin{
+ background-color: white;
+}
+
+.close_whats_new{
+ color:white
+}
+
+#whats_new h3{
+ color: #3C3C3C;
+}
+
+#whats_new button{
+ background-color: #ECECEC;
+ color: #3C3C3C;
+}
+
+#whats_new button:hover{
+ background-color:#FFA646;
+}
+
+
+.cat-modify-footer,
+.savebar-footer {
+ border-color: #ececec;
+ background: white;
+}
+
+.cat-modify-footer-see-out,
+.savebar-see-out,
+.buttonSecond {
+ background-color: #ECECEC!important;
+ color: #3C3C3C!important;
+}
+
+.cat-modify-footer-see-out:hover,
+.savebar-see-out:hover,
+.buttonSecond:hover {
+ background-color: #F29F4B!important;
+ color: #3C3C3C!important;
+}
+
+.cat-modify-footer-see-out:focus {
+ border: 2px solid #F4AB4F;
+ background: #ECECEC;
+}
+
+.cat-modify-footer-see-out.disabled {
+ background-color: #ECECEC;
+ color: #B8B8B8;
+}
+
+.RenameTagPopInContainer {
+ background-color:#fff;
+}
+
+/* Filters options */
+label:has(> .filters-icon-check:disabled), span:has(+ .filters-icon-check:disabled){
+ color: #D5D5D5 !important;
+ cursor: not-allowed;
+}
+
+.select-views{
+ background-color: #f3f3f3;
+}
+
+.filter-manager-options-container{
+ color: #474747;
+}
+
+.filter-manager-options-container:hover{
+ background-color: #EDEDED;
+}
+
+.filter-manager-options-container.selected-filter-container{
+ background-color: #777777;
+ color: #FFFFFF;
+}
+
+.filter-manager-options-container.selected-filter-container:hover{
+ background-color: #5D5D5D;
+}
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/themes/clear/themeconf.inc.php b/Piwingo/piwigo-data/piwigo/admin/themes/clear/themeconf.inc.php
new file mode 100644
index 0000000..4b6ccff
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/themes/clear/themeconf.inc.php
@@ -0,0 +1,8 @@
+ 'clear',
+ 'parent' => 'default',
+ 'admin_icon_dir' => 'admin/themes/clear/icon',
+ 'colorscheme' => 'clear',
+);
+?>
diff --git a/Piwingo/piwigo-data/piwigo/admin/themes/default/css/components/album_selector.css b/Piwingo/piwigo-data/piwigo/admin/themes/default/css/components/album_selector.css
new file mode 100644
index 0000000..ad23fd3
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/themes/default/css/components/album_selector.css
@@ -0,0 +1,291 @@
+#addLinkedAlbum {
+ display:none;
+}
+
+.linkedAlbumPopIn {
+ position: fixed;
+ z-index: 102;
+ left: 0;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ overflow: auto;
+ background-color: rgba(0,0,0,0.7);
+}
+
+.linkedAlbumPopInContainer {
+ display:flex;
+ position:absolute;
+ left:50%;
+ top: 50%;
+ transform:translate(-50%, -48%);
+ text-align:left;
+ padding:20px;
+ flex-direction:column;
+ border-radius:15px;
+ align-items:center;
+ width: 460px;
+ height: 400px;
+}
+
+.linkedAlbumPopInContainer.big {
+ height: 500px;
+}
+
+.ClosePopIn {
+ position: absolute;
+ right: -40px;
+ top: -40px;
+ font-size: 30px;
+ color: #FFF;
+}
+
+.ClosePopIn:hover {
+ text-decoration: none;
+ cursor: pointer;
+}
+
+.linkedAlbumPopInContainer .AddIconContainer {
+ margin-top: 20px;
+}
+
+.linkedAlbumPopInContainer .AddIcon {
+ border-radius: 9999px;
+ padding: 10px;
+ font-size: 2em;
+}
+
+.linkedAlbumPopInContainer .AddIconTitle {
+ font-size: 1.4em;
+ font-weight: bold;
+ text-align: center;
+ margin-bottom: 10px;
+ margin-top: 15px;
+}
+
+#linkedAlbumSearch .search-icon {
+ position: absolute;
+ transform: translate(7px, 8px);
+ font-size: 18px;
+ top: auto;
+}
+
+.search-cancel-linked-album {
+ opacity: 0.4;
+ cursor: pointer;
+ position: absolute;
+ font-size: 18px;
+ transform: translate(215px, 8px);
+}
+
+.search-cancel-linked-album:hover {
+ opacity: 1;
+}
+
+.linkedAlbumPopInContainer .searching {
+ margin-top: 10px;
+}
+
+.linkedAlbumPopInContainer #searchResult {
+ width: 100%;
+ overflow-y: auto;
+ max-height: 400px;
+ margin: 10px 0 0 0;
+}
+
+.put-to-root {
+ width: 220px;
+ margin-top: 5px;
+}
+.put-to-root p {
+ margin: 0 auto;
+}
+
+/* Prefill */
+.display-subcat {
+ margin-right: 2px;
+}
+
+.display-subcat:hover {
+ cursor: pointer;
+}
+
+.display-subcat::before {
+ transition: 0.5s;
+ transform: rotate(90deg);
+}
+
+.display-subcat.open::before {
+ transform: rotate(180deg);
+}
+
+.search-result-item {
+ margin: 10px 0px;
+ padding: 5px 10px;
+ height: 25px;
+ border-radius: 5px;
+ font-weight: bold;
+ display: flex;
+ align-items: center;
+ cursor: pointer;
+}
+
+.search-result-item .item-add {
+ margin-left: auto;
+ cursor: pointer;
+}
+
+.notClickable {
+ opacity: 0.3;
+ cursor: default;
+}
+
+.notClickable:hover {
+ cursor: default;
+}
+
+.search-result-item.already-in {
+ cursor: default;
+}
+
+.prefill-results-item {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ align-items: center;
+}
+
+.search-result-path {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ max-width: 350px;
+ direction: rtl;
+ text-align: left;
+}
+
+.search-result-path.not-rtl {
+ direction: ltr !important;
+ text-overflow: unset !important;
+}
+
+.search-result-path-name {
+ unicode-bidi: plaintext;
+}
+
+.search-result-subcat-item {
+ display: none;
+}
+
+.and-more{
+ text-align: center;
+}
+
+/* Album selector View */
+.album-create {
+ display: flex;
+ width: 100%;
+ height: 100%;
+ flex-direction: column;
+}
+
+.album-selector,
+.album-create {
+ text-align: center;
+}
+
+.linked-album-subtitle {
+ margin: 0 0 30px 0;
+}
+
+.linked-album-subtitle p {
+ margin: 0;
+ font-style: italic;
+ font-weight: 700;
+ color: #AAAAAA;
+}
+
+.linked-add-album {
+ display: none;
+ margin: 0px;
+}
+
+.album-switch-bottom {
+ width: 100%;
+ margin-top: auto;
+}
+
+.album-switch-container {
+ width: 100%;
+ display: flex;
+ flex-wrap: wrap;
+ margin-top: 5px;
+ align-items: center;
+ justify-content: space-between;
+ height: 40px;
+}
+
+.switch-input {
+ display: flex;
+ align-items: center;
+}
+
+.linked-album-input-container {
+ width: 100%;
+ text-align: start;
+}
+
+.linked-album-input-container.album-name {
+ margin-bottom: 20px;
+}
+
+.linked-album-input-container .user-property-input,
+.linked-add-radio-input {
+ margin-top: 10px;
+}
+
+.linked-add-radio-input {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ margin-bottom: 10px;
+}
+
+.linked-add-radio-input input {
+ margin-right: 5px;
+}
+
+.linked-add-radio-input label {
+ font-size: 12px;
+ font-weight: 600;
+}
+
+.linked-album-create-btn {
+ display: flex;
+ margin-top: auto;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.linked-album-create-btn p {
+ margin: 0;
+}
+
+.linked-button-cancel {
+ cursor: pointer;
+ font-weight: 700;
+}
+
+.linked-button-cancel:hover {
+ color: #000;
+}
+
+.AddAlbumErrors {
+ visibility: hidden;
+}
+
+#linkedAddAlbumErrors {
+ margin: 0;
+ text-align: start;
+ padding: 10px;
+}
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/themes/default/css/components/general.css b/Piwingo/piwigo-data/piwigo/admin/themes/default/css/components/general.css
new file mode 100644
index 0000000..a0c3998
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/themes/default/css/components/general.css
@@ -0,0 +1,331 @@
+/* -------------
+Head Buttons
+-------------
+
+.head-button-1
+
+or
+
+.head-button-2
+
+*/
+
+.head-button-1, .head-button-2 {
+ position: relative;
+ padding: 10px;
+ border-radius: 5px;
+ font-weight: bold;
+ display: flex;
+ align-items: baseline;
+ cursor: pointer;
+ margin-right: 10px;
+}
+
+.head-button-1:active, .head-button-2:active {
+ box-shadow: none;
+ transform: translateY(2px);
+}
+
+.head-button-1 {
+ color: white;
+ background: #ffa646;
+ box-shadow: 0px 2px #bb7932;
+}
+
+.head-button-1 p, .head-button-2 p {
+ margin: 0;
+ white-space: nowrap;
+}
+
+.head-button-1:hover {
+ background: #ff7700;
+ text-decoration: none !important;
+ color: white;
+ transition: all 125ms ease-out;
+}
+
+.head-button-2 {
+ background: #fafafa;
+ box-shadow: 0px 2px #00000024;
+}
+
+.head-button-2:hover {
+ text-decoration: none !important;
+ color: inherit !important;
+}
+
+/* -------------
+Advanced filter
+-------------
+
+.advanced-filter-btn.icon-filter(.advanced-filter-open)
+...
+.advanced-filter(.advanced-filter-open)
+ .advanced-filter-header
+ .advanced-filter-title
+ .advanced-filter-close.icon-cancel
+ .advanced-filter-container
+ .advanced-filter-item
+ .advanced-filter-item-label
+ .advanced-filter-item-container
+ // Put here your filter
+ ...
+*/
+
+.advanced-filter-btn {
+ width: 70px;
+ z-index: 2;
+ position: relative;
+ cursor: pointer;
+ padding: 10px;
+ text-align: center;
+ font-weight: bold;
+ background-color: #F3F3F3;
+}
+
+.advanced-filter-btn::before { /* Change icon size */
+ font-size: 14px;
+}
+
+.advanced-filter-btn.advanced-filter-open::after {
+ content: "";
+ display: block;
+ width: 100%;
+ height: 16px;
+ background-color: inherit;
+ bottom: -16px;
+ left: 0;
+ position: absolute;
+}
+
+.advanced-filter {
+ display: none;
+ padding: 15px;
+ font-size: 1em;
+ flex-direction: column;
+
+ background-color: #F3F3F3;
+}
+
+.advanced-filter.advanced-filter-open {
+ display: flex;
+}
+
+.advanced-filter-header {
+ display: flex;
+ justify-content: space-between;
+ margin-bottom: 10px;
+}
+
+.advanced-filter-title {
+ font-weight: bold;
+
+ color: #3e3e3e;
+}
+
+.advanced-filter-close {
+ font-size: 1.8em;
+ color: #C5C5C5;
+ cursor: pointer;
+}
+
+.advanced-filter-close:hover {
+ color: #ff7700;
+}
+
+.advanced-filter-container {
+ display: flex;
+}
+
+.advanced-filter-item:not(:last-child) {
+ margin-right: 30px;
+}
+
+.advanced-filter-item-label {
+ text-align: left;
+ display: flex;
+ margin-bottom: 5px;
+
+ color:#3e3e3e;
+}
+
+.advanced-filter-item-container {
+ position: relative;
+ text-align: left;
+ width: 100%;
+}
+
+/* Set Margin if the last element is a slider */
+.advanced-filter-item:last-child .advanced-filter-item-container .slider-bar-wrapper {
+ margin-right: 10px;
+}
+
+/* -------------
+Advanced filter Select
+-------------
+
+.advanced-filter-select-container
+ select.advanced-filter-select
+
+or (generated by selectize.js)
+
+.advanced-filter-item-container
+ .selectize-control
+ .selectize-input
+*/
+
+.user-action-select-container::before, .advanced-filter-select-container::before {
+ content: '\e835'; font-size: 14px; position: absolute; font-family: "fontello"; color: #6E6E6E; pointer-events: none;
+}
+
+.advanced-filter-select-container::before {
+ top: 8px; right:10px
+}
+
+.advanced-filter-select {
+ display: block;
+ border: solid 1px #D4D4D4;
+ padding: 8px 10px;
+ height: 34px;
+ background: white;
+}
+
+.advanced-filter-item-container .selectize-control .selectize-input {
+ border: solid 1px #D4D4D4 !important;
+ padding: 8px 10px !important;
+ height: 34px;
+ background: white !important;
+ box-shadow: none !important;
+}
+
+.advanced-filter-item-container .selectize-control .selectize-input .item {
+ padding-right: 0 !important;
+}
+
+/* -------------
+Info Framed
+-------------
+
+.info-framed
+ .info-framed-icon
+ i or img
+ .info-framed-container
+ .info-framed-title
+ div
+ div
+ ...
+
+*/
+
+.info-framed {
+ display: flex;
+ border: #EEE solid 2px;
+ padding: 20px;
+ border-radius: 5px;
+ margin: 0px 10px;
+ align-items: center;
+}
+
+a.info-framed:hover {
+ color: inherit;
+ text-decoration: none;
+}
+
+.info-framed-icon {
+ font-size: 34px;
+ margin-right: 20px;
+ display: flex;
+ color: #3c3c3c;
+}
+
+.info-framed-icon i {
+ margin: auto;
+}
+
+.info-framed-container {
+ margin: 0;
+ display: inline-table;
+}
+
+.info-framed-container > * {
+ margin: 0;
+ word-wrap: anywhere;
+}
+
+.info-framed-title {
+ color: #3c3c3c;
+ font-weight: bold;
+}
+
+/* -------------
+Info
+-------------
+
+.info-message.icon-*, .info-warning.icon-*, .info-error.icon-*
+ p
+ (a)
+
+*/
+
+.info-message, .info-warning, .info-error {
+ height: 35px;
+ overflow: hidden;
+ border-radius: 20px;
+ display: flex;
+ padding: 0px 10px 0px 0px;
+ font-weight: bold;
+ margin-left: 10px;
+}
+
+.info.hide {
+ display: none;
+}
+
+.info-message p, .info-warning p, .info-error p {
+ margin: auto;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ text-align: initial;
+}
+
+.info-message::before, .info-warning::before, .info-error::before {
+ line-height: 35px;
+ margin: 0px 10px;
+ font-size: 16px;
+}
+
+.info-warning {
+ color: #ee8800;
+ background-color:#ffdd99;
+}
+
+.info-message {
+ display: none;
+ background-color: #c2f5c2;
+ color: #0a0;
+}
+
+.info-error {
+ color: #f22;
+ background-color: #ffd5dc;
+ display: none;
+ animation-name: info-error-appear ;
+ animation-duration: 0.4s;
+ animation-timing-function: ease;
+}
+
+.info-message a:hover, .info-warning a:hover, .info-error a:hover {
+ color: white;
+}
+
+@keyframes info-error-appear {
+ 25% { transform: translateX(-10px)}
+ 50% { transform: translateX(10px)}
+ 75% { transform: translateX(-10px)}
+ 100% { transform: translateX(0px)}
+ }
+
+.tree .badge-container i.icon-imagefolder-01.nb-sub-photos:before{
+ margin-right:0.5em!important;
+}
\ No newline at end of file
diff --git a/Piwingo/piwigo-data/piwigo/admin/themes/default/fontello/LICENSE.txt b/Piwingo/piwigo-data/piwigo/admin/themes/default/fontello/LICENSE.txt
new file mode 100644
index 0000000..c3966fc
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/themes/default/fontello/LICENSE.txt
@@ -0,0 +1,75 @@
+Font license info
+
+
+## Font Awesome
+
+ Copyright (C) 2016 by Dave Gandy
+
+ Author: Dave Gandy
+ License: SIL ()
+ Homepage: http://fortawesome.github.com/Font-Awesome/
+
+
+## Typicons
+
+ (c) Stephen Hutchings 2012
+
+ Author: Stephen Hutchings
+ License: SIL (http://scripts.sil.org/OFL)
+ Homepage: http://typicons.com/
+
+
+## Entypo
+
+ Copyright (C) 2012 by Daniel Bruce
+
+ Author: Daniel Bruce
+ License: SIL (http://scripts.sil.org/OFL)
+ Homepage: http://www.entypo.com
+
+
+## MFG Labs
+
+ Copyright (C) 2012 by Daniel Bruce
+
+ Author: MFG Labs
+ License: SIL (http://scripts.sil.org/OFL)
+ Homepage: http://www.mfglabs.com/
+
+
+## Elusive
+
+ Copyright (C) 2013 by Aristeides Stathopoulos
+
+ Author: Aristeides Stathopoulos
+ License: SIL (http://scripts.sil.org/OFL)
+ Homepage: http://aristeides.com/
+
+
+## Iconic
+
+ Copyright (C) 2012 by P.J. Onori
+
+ Author: P.J. Onori
+ License: SIL (http://scripts.sil.org/OFL)
+ Homepage: http://somerandomdude.com/work/iconic/
+
+
+## Fontelico
+
+ Copyright (C) 2012 by Fontello project
+
+ Author: Crowdsourced, for Fontello project
+ License: SIL (http://scripts.sil.org/OFL)
+ Homepage: http://fontello.com
+
+
+## Web Symbols
+
+ Copyright (c) 2011 by Just Be Nice studio. All rights reserved.
+
+ Author: Just Be Nice studio
+ License: SIL (http://scripts.sil.org/OFL)
+ Homepage: http://www.justbenicestudio.com/
+
+
diff --git a/Piwingo/piwigo-data/piwigo/admin/themes/default/fontello/README.txt b/Piwingo/piwigo-data/piwigo/admin/themes/default/fontello/README.txt
new file mode 100644
index 0000000..d870892
--- /dev/null
+++ b/Piwingo/piwigo-data/piwigo/admin/themes/default/fontello/README.txt
@@ -0,0 +1,75 @@
+This webfont is generated by https://fontello.com open source project.
+
+
+================================================================================
+Please, note, that you should obey original font licenses, used to make this
+webfont pack. Details available in LICENSE.txt file.
+
+- Usually, it's enough to publish content of LICENSE.txt file somewhere on your
+ site in "About" section.
+
+- If your project is open-source, usually, it will be ok to make LICENSE.txt
+ file publicly available in your repository.
+
+- Fonts, used in Fontello, don't require a clickable link on your site.
+ But any kind of additional authors crediting is welcome.
+================================================================================
+
+
+Comments on archive content
+---------------------------
+
+- /font/* - fonts in different formats
+
+- /css/* - different kinds of css, for all situations. Should be ok with
+ twitter bootstrap. Also, you can skip style and assign icon classes
+ directly to text elements, if you don't mind about IE7.
+
+- demo.html - demo file, to show your webfont content
+
+- LICENSE.txt - license info about source fonts, used to build your one.
+
+- config.json - keeps your settings. You can import it back into fontello
+ anytime, to continue your work
+
+
+Why so many CSS files ?
+-----------------------
+
+Because we like to fit all your needs :)
+
+- basic file, .css - is usually enough, it contains @font-face
+ and character code definitions
+
+- *-ie7.css - if you need IE7 support, but still don't wish to put char codes
+ directly into html
+
+- *-codes.css and *-ie7-codes.css - if you like to use your own @font-face
+ rules, but still wish to benefit from css generation. That can be very
+ convenient for automated asset build systems. When you need to update font -
+ no need to manually edit files, just override old version with archive
+ content. See fontello source code for examples.
+
+- *-embedded.css - basic css file, but with embedded WOFF font, to avoid
+ CORS issues in Firefox and IE9+, when fonts are hosted on the separate domain.
+ We strongly recommend to resolve this issue by `Access-Control-Allow-Origin`
+ server headers. But if you ok with dirty hack - this file is for you. Note,
+ that data url moved to separate @font-face to avoid problems with
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ⌂ icon-code0x2302
+
+
+ icon-add-album0xe73e
+
+
+ icon-puzzle0xe7b6
+
+
+ icon-language0xe800
+
+
+
+
+ icon-signal0xe801
+
+
+ icon-users0xe802
+
+
+ icon-tools0xe803
+
+
+ icon-arrows-cw0xe804
+
+
+
+
+ icon-exchange0xe805
+
+
+ icon-folder-open0xe806
+
+
+ icon-brush0xe807
+
+
+ icon-flow-branch0xe808
+
+
+
+
+ icon-menu0xe809
+
+
+ icon-star-half0xe80a
+
+
+ icon-user-add0xe80b
+
+
+ icon-cw0xe80c
+
+
+
+
+ icon-group0xe80d
+
+
+ icon-globe0xe80e
+
+
+ icon-equalizer0xe80f
+
+
+ icon-mail-10xe810
+
+
+
+
+ icon-search0xe811
+
+
+ icon-move0xe812
+
+
+ icon-upload0xe813
+
+
+ icon-upload-cloud0xe814
+
+
+
+
+ icon-key0xe815
+
+
+ icon-network0xe816
+
+
+ icon-info-circled-10xe817
+
+
+ icon-calendar0xe818
+
+
+
+
+ icon-ok0xe819
+
+
+ icon-help-circled0xe81a
+
+
+ icon-logout0xe81b
+
+
+ icon-flag0xe81c
+
+
+
+
+ icon-spin60xe81d
+
+
+ icon-hourglass0xe81e
+
+
+ icon-check0xe81f
+
+
+ icon-check-empty0xe820
+
+
+
+
+ icon-cancel-circled0xe821
+
+
+ icon-cancel0xe822
+
+
+ icon-plus0xe823
+
+
+ icon-ok-circled0xe824
+
+
+
+
+ icon-heart-broken0xe825
+
+
+ icon-download0xe826
+
+
+ icon-zoom-in0xe827
+
+
+ icon-zoom-out0xe828
+
+
+
+
+ icon-attention0xe829
+
+
+ icon-back-in-time0xe82a
+
+
+ icon-ccw0xe82b
+
+
+ icon-eye-off0xe82c
+
+
+
+
+ icon-user0xe82d
+
+
+ icon-moon-inv0xe82e
+
+
+ icon-sun-inv0xe82f
+
+
+ icon-book0xe830
+
+
+
+
+ icon-chart-bar0xe831
+
+
+ icon-floppy0xe832
+
+
+ icon-th0xe833
+
+
+ icon-th-list0xe834
+
+
+
+
+ icon-down-open0xe835
+
+
+ icon-left-open0xe836
+
+
+ icon-arrow-combo0xe837
+
+
+ icon-th-10xe838
+
+
+
+
+ icon-flow-tree0xe839
+
+
+ icon-link-10xe83a
+
+
+ icon-heart0xe83b
+
+
+ icon-home0xe83c
+
+
+
+
+ icon-users-10xe83d
+
+
+ icon-clone0xe83e
+
+
+ icon-object-group0xe83f
+
+
+ icon-ellipsis-v0xe840
+
+
+
+
+ icon-users-cog0xe841
+
+
+ icon-trash-10xe842
+
+
+ icon-zoom-square0xe843
+
+
+ icon-grip-vertical-solid0xe844
+
+
+
+
+ icon-dice-solid0xe845
+
+
+ icon-mail0xe846
+
+
+ icon-star0xe847
+
+
+ icon-star-empty0xe848
+
+
+
+
+ icon-picture0xe849
+
+
+ icon-plus-circled0xe84a
+
+
+ icon-link0xe84b
+
+
+ icon-lock0xe84c
+
+
+
+
+ icon-eye0xe84d
+
+
+ icon-tags0xe84e
+
+
+ icon-pencil0xe84f
+
+
+ icon-chat0xe850
+
+
+
+
+ icon-trash0xe851
+
+
+ icon-cog0xe852
+
+
+ icon-cog-alt0xe853
+
+
+ icon-wrench0xe854
+
+
+
+
+ icon-basket0xe855
+
+
+ icon-clock0xe856
+
+
+ icon-block0xe857
+
+
+ icon-shuffle0xe858
+
+
+
+
+ icon-asl0xe859
+
+
+ icon-pause0xe85a
+
+
+ icon-th-large0xe85b
+
+
+ icon-th-list-10xe85c
+
+
+
+
+ icon-fire0xe85d
+
+
+ icon-cone0xe85e
+
+
+ icon-king0xe85f
+
+
+ icon-user-10xe86c
+
+
+
+
+ icon-user-minus0xe86d
+
+
+ icon-robot-head0xe87e
+
+
+ icon-pulse0xe87f
+
+
+ icon-resize-full0xe88e
+
+
+
+
+ icon-resize-small0xe88f
+
+
+ icon-piwigo0xe89e
+
+
+ icon-imagefolder-010xe999
+
+
+ icon-hdd0xf0a0
+
+
+
+
+ icon-tasks0xf0ae
+
+
+ icon-filter0xf0b0
+
+
+ icon-docs0xf0c5
+
+
+ icon-list-bullet0xf0ca
+
+
+
+
+ icon-mail-alt0xf0e0
+
+
+ icon-sitemap0xf0e8
+
+
+ icon-bell0xf0f3
+
+
+ icon-circle-empty0xf10c
+
+
+
+
+ icon-crop0xf125
+
+
+ icon-ellipsis0xf141
+
+
+ icon-ellipsis-vert0xf142
+
+
+ icon-sort-name-up0xf15d
+
+
+
+
+ icon-sort-alt-up0xf160
+
+
+ icon-sort-alt-down0xf161
+
+
+ icon-sort-number-up0xf162
+
+
+ icon-thumbs-up0xf164
+
+
+
+
+ icon-down0xf175
+
+
+ icon-up0xf176
+
+
+ icon-right0xf178
+
+
+ icon-dot-circled0xf192
+
+
+
+
+ icon-database0xf1c0
+
+
+ icon-file-image0xf1c5
+
+
+ icon-file-code0xf1c9
+
+
+ icon-lifebuoy0xf1cd
+
+
+
+
+ icon-toggle-off0xf204
+
+
+ icon-toggle-on0xf205
+
+
+ icon-user-secret0xf21b
+
+
+ icon-television0xf26c
+
+
+
+
+
+
diff --git a/Piwingo/piwigo-data/piwigo/admin/themes/default/fontello/font/fontello.eot b/Piwingo/piwigo-data/piwigo/admin/themes/default/fontello/font/fontello.eot
new file mode 100644
index 0000000000000000000000000000000000000000..0110a2f8ff69da3e6ebd0cd03b1e627865073b56
GIT binary patch
literal 44828
zcmd?Sdwg8geJ{G!+K<_@XJ*f9&qJfpXf#i~Jd#JF8CjO)u`J87EZeed3y_cKxB$FnW*o5X1*BamN
zZ;xaP64Kny`SaRd`?Y?1&)#dT-|PGPt>x&K7(4nTW1I;_e*{w`>i}2o=5#bVRy)7C
zwJzgy<-YufuU?%!@~}PZMs|oDWxLry{Jjws1{=rOUiLwp?_@`CCCDal$;_qt<8W6$BeH|)y&2KRsdRh&Ba?!4(Ru6uC)EcV*ogCE{=
z;{K6yj5$s*c8A!vd*@{9h49ZA`;$9RU)+Za+AT^q&cBB9)V>>z9{<1p>GE!z{~KB`
zb@0aPcK+fv*IzMquZDLpZ`gVKut>O1GWO{x=;McW-mv@IpR335r~5$v?ZY?TbhISx
zeV(!Vos21u9X_)A@X6;EKF8P>zYqEctZ&!RIQ>iv4vns7#=)IO53vZ7QA>ZQZRQ^H
zgZuaHWcY2XhNF&ZIj(S~&eBWw^ShaX-@jQ0
zink6*(;%1~6g65JOn5eWi?MbT{JylSMkBW1Dp9v%uUpq;(TVdxR>nPY
zQv9_4r_WWkS8k|$v~s5M;LkpD{-N_vo`356H_pFu{*CjM^S`>_ypX;yaAE6(T^A-V
z9J_G*!aWzhcHtWr{`-Y*zoooY|JK3Fml>OR3acEfoUGjSzE4?#r|iH}KKQPu$g@wu
zTm7&7;rJ@+FBe?qD%alkug-OD;IHRhe|_AC7a-=8(1r?n&xT&Kqum_L$y{J8H^!}(
z`Iw)XEC99&u`sK{*r;bw*1%${k;PdPORywMu{6uDENf;htd+H){pW$@Ixw#0vpnl!
z1=h`qti*cQ0@lkGvOcy5BW^KzWeFQ#OYt4c*brOJhS>@>!d9|Twu-H0YuFfD3-(^e
z*0XEC)En4Fwux?7DE|NZAIJ*ERFYiu
z2d$C>*HIzv`e}cyVC1l$LXuD+ZmeKOg*dVTIx57e70^*3`A{J`;#?c{M2AAsq(XGW
z)pqQOj(PzcTp>CXj7e4@IuwjfRv|hRj8j%2IuwjpRv|hRj9peCI{Few-wM&8U_7%5
z(V<{uvkK9nV2ra0(V<|pvkK9nVBE6`(Gjl%u_rnd@B*t49SXRDRfrA+{J|h3HVgN3240DBvhoAvzTB7OM~)3b>3_hz
zvI^0mfE!tb=up6ytU`1s;80c}Iu!6Ks}LOuxRzCj4h8(nDny3@PG%LNLjg~-3elmE
z)U6O53izB=hz2IuuA6Rv|hR$Q)K7IuuABRv|hR$RSoC
zIuuAGRv|hR$R<`HIuusMp6E~@uULiXP$0Qjh3HTq!&rsrP$11%h3HTq*I0$sW>8P$2bKh3HTq|5%0SP#_6eh3HTq6Iq4mP#_&yh3HTqCs~E)P#`f`h3HTq
zJ6VP3P#{HFh3HTqPg#ZNP#{@Zh3HTqV_AjhP#|qth3HTqcUgt#P#}R>h3HTqi&=%}
zP#~3Ah3HTqpIL?IP#~#Uh3HTqvss1cP$0coh3HTq$61BwP$1D+h3HTq+gXL^P}mOa
zi4Fzwo>hnr1(KgthzG@Y`1zL!mf1_5Q
zkJ$N2t&p*L{#UgEW0hTS)(Xs9b|GCW&|B;R#t{{0Fm?gshzfKWyMXqf0&p?81Mq73ffQ;oG$WZOYz~YXy3hy`|I&G%S0ozE+@X*;{BwDx_aXe_VcE
z4vH5beN*7#Sh+su6^!#yiF3wp7aZT;U1-jRe6kvDOWV{$mS+kjUd%W0py}qJpvfhJ
zckmo9`TKbzk8wL!6CEI0%(Jv9=0l+58>5P$Rxhb4mlcm3Rn;H-K;?t42}4b2D*ujf
z+LAVn9|VP=Miu1;KTwn?4ne&Pr(D6^Tvk!#k$?CD)ex(vJ8YU{mzlqsglLRQ5T
zgRP9OoPwZn9cp7+8f{_lWK$x?
z@yVrPS5rO|%m$hgHq|Y%nUc3qDlX)>*1)MI!~>?pi+D1T#kNo^b#)hr4rE;*
z3&@N8Uk`6;p1#v;;J&X%TiY|@g8{?yx7Eg;1q;((7o7737T
zK2LY;(p8(&F>|ch)gO6-zlgQD(}7v!Gebc&n@nV~Xp&H{D_<;RvS`jssn$frYz7DUpv|)IbX0Yk|`82!5|)&YrNZI=;q*L8P&RZZBx#yH^WpNsSB7q*K{paTejEb
zA4wO*zkr{XK!aQd3Anqwt1TgHd{1{+61EUpXpuu`(g0VqK8!3y9Yx#m+nG(+Zl^KN
z6uCA8$xqOPw4Z5;qHSQBrfg@5rmWdLdEJg{H&0wMzIJ$dPcfVJ+tpAT52`j|y;48V
z8d5gLyD{oYS%YT_neI%nt5nDqy7Hxb121+JLuN1#bn^gOP6?K>s!cUZ{TQmrgqlnT
zeL)jl)16JCALyXyr(r2|NzxBvW7~8Q7xF}Zt0y-+*;6R@<;&tur>qNAen4nBRew;`
zgeGfGIVWzZJ{nEPiAein(Y~0L>Jyr%_UjX4@`Rdys#B;Fvi_*hcIda>JR4|>&to1WLT)82=0s?lJVGmLHtlFN^H;Y8>;hlXSDs+V0hz@>J#Up
z)i>W!ydP~ZG|NPWBEO3$~sBMygu
zBwL>jWPQDDzHD3RKtIp)kGGcU{jI&e7Js@vJK}fentk5BK!E>4!V^!<+t?!tTiTLw
zPomRk^6E}gkN0`(X4v*|hb@z6b=GBkiFRH0sJc4=9VB1Ac=>+mS5gEPeF+xbHr7y%
zY}!~}EVC65;?T6vH^&;H^%1W}LR
zJcH&>2W@ILlAzS;#ObB(
zekk%_2pt%dR;K>#Gi&eb8+Js4LF1wk6!ulklckYcvuap&f@clWQ@c8TcqJ}|6z7dL
zCr|z4Gi&dso5EzY-1|cRf?B_3wxhl_4f?=Vz|3>5ab>R
zw#J|Fhx}3Sb3-&Bq*I_L9
z;77NYTbLwE_?D}79FxVnthZ!uve>Pt_2}9;RvUT>FHSbwtjRWGiQ%eT=liShL}vP|
zKgzu?h9}ZuyFd1|YG?P6+8BmQxEDkZW
zK68{$5Jq(Q1u-QFpb6dZyqB|$ioimWOp@o^eP1()~R
zIUEXQ6Lt#miNe;F7nh2IOBXLMFJIVO>@W2fx;i`BT1kXihMj3MB>D%@kC6a<;H?>K
z&;$YK2~nz@DrS&OyM*em?aUybJrGkPYWwQmTx)9~EDsG$4h;{}rg>LyA#a^eKik~X
z+S=1R7^Q79f1A)$QPnR_w`i9#XP@1bD+)uW{1F*B=K(-2OWqCLjH9fMh
zLC(l%uPgQ~+6^39GjCOhWJzqmPDtAow4<~J7V7-Yj@-QVw$_%quwTO)rAelAlWhUd
zfQ*6yiP>xh!p6;m0UBm-rGn|MKoW*Svb(FhOB{Um(i^GVwxOIx#-c21vbyEpwm=^V
z!!U%N8|H)e-aCnZQ{~5O!GOqdRt;?bkUjanialbz07G1xcsCehw&
zwdLjN<)@`hkT;!dQMq>>=ZYN~9G?iq0!xv^C%%NlCua)Z4~J0}n;<^rooEPoZ8q!A
zrmT@M>;G9g!w_anz{|l`k{69nvL$k&U#h8(poCFzG358I8b927U^JH-J