Zenphoto 1.6

    This is a minor security and a minor-major release including some structural changes as well as bugfixes.

    Developer note

    The plan is that the 1.6.x release is the last 1.x release before our long planned "major release". We therefore consider 1.x to be feature freezed and will only do bug fixes. All standard themes and some plugins have also been deprecated.

    We need to basically close 1.x as we otherwise will never get the "next major release" ready. That release also will have a lot of internal changes that don't match 1.x, so maintaining changes in two release streams causes a lot of overhead for which we don't have the resources anymore.

    The 1.6 release features a few core changes which are an indication of much more internal changes to come in the "next major release". You should not notice these changes if you are using officially included themes and plugins. If you created themes or plugins yourself or use older third party themes and plugins we cannot guarantee that. Please review the debug log if you notice any issues.

    Requirements changed

    • Minimum requirement PHP 7, PHP 8 recommended – PHP 8 and 8.1 supported (probably 8.2 as well although we are not able to test that yet).. This may be the last release with PHP 7 support.
    • Zenphoto expects native PHP core extensions to be available and may not specifically check or warn about these. Certain missing  PHP bundled or externral extensions recommended or required will be noted on setup as usual. General info: https://www.php.net/manual/en/extensions.membership.php 
    • jQuery 3.6.1 + jQuery UI 1.13.2 update. We also included the jQuery Migrate 3.4.0 plugin so legacy jQuery code and tools should still work. Very old browser may have problems in various JS related areas and this will not be fixed. More info about this on https://jquery.com/browser-support/ 

    Setup behaviour changes

    • Setup on the first page will now report issues only. The setup log will contain the full info if needed. The 2nd page is as always.
    • Note on fresh install: You can only once enter database credentials via the setup form. Once the config file is created and you have wrong credentials you have to enter them in the file itself via FTP. We only consider it a "fresh" install as long as there is no config file present. The reason for this is that without db credentials we cannot check for authorized setup access and the form would be open to any visitor coming by to enter any db credential. This is a potential security risk.
    • Also the site is now in maintenance mode (see the info below) as soon as setup is started to block any outside access disturbing it.

    Database utf8mb4 support

    Long overdue Zenphoto now supports full UTF-8 aka utf8mb4 collations. For a long time Zenphoto used the collation utf8_unicode_ci for new tables already. If your database server supports it, new tables (and its text columns) will now be created using utf8mb4_unicode_ci or utf8mb4_unicode_520_ci

    If you are doing an upgrade and already have utf8_* collation tables with all columns using any utf8_* collation, setup will attempt to change the collation to one of the above utf8mb4 collations. There should not be any issues since UTF-8 should be compatible. However we can never guarantee this. Before updates you should therefore always make a database backup anyway.

    Tables that are not fully using any utf8_* collation – like those from an old install that use latin1 or similar – will not be changed as there might be more complicated conversions of the data necessary to not break anything. Especially if you are using non Western European encodings. [acrylian, fretzl - Special thanks to kochs-online, bic, MarkRH, eclrgp]

    Special note for theme authors regarding PHP 8.1:

    The old common way of using the native @call_user_func('somePluginFunction") to suppress errors of non available functions from plugins which are not enabled is not compatible with PHP 8+. This will cause a TypeError similar to a Fatal Error and break your theme. We introduced a new function callUserFunction() as a compatible replacement.


    • elFinder has been updated to fix some security related issue [fretzl, acrylian]
    • backup_restore utility:
      • File names now get a random key appended so they are not that easy to guess
      • The backup folder can now be renamed and optionally be placed outside the webroot, just like the albums folder, via the config file. Use $conf['backupfolder_folder']  and $conf['backup_folder_class']. Otherwise it follows the documentation of the albums folder. Note that the folder of course must exist in the location defined, as it will not be created automatically [acrylian - Thanks to abdulrahman|
    • Serveral PHP object injection issues with unserialize() usages fixes. Also adds additional parameter to getSerializedArray(). This affected the plugins GoogleMaps, register_user, and user_expiry [acrylian - Thanks to abdulrahman]
    • XSS issue with searchform [acrylian – Thanks to JPCERT]

    General changes and fixes

    • All functions and class methods deprecated for 1.6 have now been removed. See also the section about changed deprecation handling below [acrylian]
    • The native PHP function strftime() has been deprecated in PHP 8.1 (https://www.php.net/manual/en/function.strftime.php) so we already removed its usage [acrylian, fretzl - Thanks to bic and kochs-online]
      • Since the strftime() date formats are not compatible with standard date() date formats we added a function to cover a general internal conversion. But you should update your custom code as otherwise there will be frequent deprecation notices in the debug log.
      • Also if you used date formats with day and/or month names the automatic translation requires the PHP (bundled) extension intl to be available.
    • Fix missing comment bulk actions on albums and images [acrylian]
    • Improve dispaly of theme and plugin deprecation notes [acrylian]
    • Changes colors of noteboxes (now blue, formerly orange) and warningboxes (now orange, formerly yelllow) [acrylian, fretzl]
    • Fix image processor issue with webp images that didn't allow the suffix [acrylian, fretz – Thanks to sam-19 and sbillard]
    • New thumb transition page handling: You now have much more control over how many image thumbs will be shown [acrylian, fretzl]
    • Fix an issue with maxspace thumbs of default and custom sidecar images [acrylian, fretzl - Thanks to kjonescubist]
    • Debug modes can now be enabled via the config file instead of hacking a core file [acrylian]
    • Fix the blocking of the Matomo widget and the tinyMCE Preview modal by adding directives to the Content-Security-Policy header [fretzl]
    • Speed improvement regarding site with lots of users and content [SubJunk]
    • Fix for avoiding duplicate options table entries on setup [SubJunk]
    • Fixes single image prev/next pagination within dynamic albums [acrylian]
    • Fix site and image custom copyright url not being saved and used properly [acrylian]
    • printCopyrightNotice() now a wrapper for gallery and image copyright nottices, [acrylian, bic-ed - Thanks to JesseC]
      • shortcuts printGalleryCopyrightNotice() and printImageCopyrightNotice() added, parameter $linked added,
      • fixes gallery and image class getCopyrightURL() methods neither using custom urls or Zenpage page urls at all.
      • Option to enable site gallery copyright notice moved from theme options to gallery options to group related options in one place.
      • Adds display image copyright notice option.
    • Admin sortorder options: Custom sort orders for all item types have been removed on the backend. [acrylian]
      • Basically MySQL code was entered here that possibly caused serious issues if used by inexperienced user both with MySQL and ZenphotoCMS and its table column names .Instead, if custom sort orders are required they should be added via the new "admin_sortbyoptions" filter or via the object model.
      • Additionally we have added some more default options.
    • Image flipping: Images can now be flipped horizontally or vertically on the image edit pages. Note that this will modify the original images. It is strongely recommended to only use this when Imagick is available as a graphics handler becuase the GDlibrary will delete embeded meta data [acrylian, fretzl]
    • Proper redirections to current page on logouts. Also a propler header request is sent to advise browsers to invalidate their caches [acrylian, fretzl, bic]
    • htmLawed 1.2.8 update [acrylian]
    • The json fallback library lib-json.php has been removed because json is already part of the PHP core for a while and now expected to be available [acrylian]
    • Fix case insenstive test failing on open_basedir restriction [brucepimenta]
    • Users – for example self-registered ones – now have the right to at least change their own user credentials. The right has also been added to the default groups where applicable. Existing users or groups will not be changed. [acrylian]
    • Fix unwanted empty album date on meta data refresh [acrylian, fretzl]
    • Fix sidecar images not being moved with their main item if using the admin move tool [acrylian – Thanks to ctdlg]

    New utilities

    • maintenance_mode: This incorporates the former site_upgrade plugin into the core.
      • You'll find a new button "Maintenance mode" on the admin overview page. It contains options to switch the modes instead of the confusing way it was before. Usage instructions are included.
      • New is that whenever you run setup the site will be closed automatically. It will not re-open automatically so you can test your site first.
      • If the site is closed or in test mode there is a clear note shown on all admin page so you don't forget to disable it.
      • Previously created custom closed.htm and rss-closed.xml placeholder within /plugins/site_upgrade/ should work as before. The former closed.php file has been abandoned and is only used if it already exists. The maintenance mode will use basic placeholders if these files are missing.


    All included themes have been marked as deprecated. A note is added on the backend.

    • basic
    • garland
    • zenpage
    • zpMobile

    They all are quite old and outdated and it does not make sense to update or rework them. They will be removed in future Zenphoto versions and they will only get bugfixes and no feature updates anymore. There will be at least one new official all-purpose theme included in the future.


    Plugins removed

    • site_upgrade: Functionality has been moved to core. See "New utilties" section above

    Deprecated plugins

    Some plugins also have been marked as deprecated. A note is added on the backend.

    • bxslider_thumb_nav: There might be a general slider replacement.
    • class-WEBdocs: There will be no actual replacement.
    • colorbox_js: There will be a replacement plugin.
    • deprecated_functions: There will be no actual replacement. Please see the section "Deprecation handling changed" below.
    • GoogleMaps: Already use the openStreetMap plugin instead.
    • jplayer: There is a core and native HTML5 player within the class-video plugin. For playlists there will be a replacement.
    • slideshow2: There might be a general slider replacement.
    • userAddressFields: There might be core functionalitly replacing this that may not be directly compatible.

    We noted these for you as preliminary information. There are several reasons:

    • Some plugins use third party libraries that have not been updated for years and likely would soon cause trouble. Some of these may get some kind of replacement.
    • Since we have limited time to maintain all the included stuff we have to remove some plugins we basically never use ourselves. These will likely not get any replacement. We welcome users to take over maintaining plugins they need themselves. 

    Some other plugins' functionality may be integrated into core as we think this makes sense but we have not listed those here yet.

    Plugin updates and changes

    • comment_form: Disable CAPTCHA option and error display if no handler is enabled [acrylian, fretzl]
    • contact_form: Disable CAPTCHA option and error display if no handler is enabled [acrylian, fretzl]
    • deprecated_functions: See section above for some info.
    • downloadList:
      • Fix broken printDownloadURL for full image [bic-ed]
      • Fix check for album existence [bic-ed]
      • Added a new 404 message for broken downloads [bic-ed]
      • Set a very fast expiring cookie after list generation for album.zip [bic-ed]
    • elFinder: Security update to 2.1.59 [acrylian - Thanks to jhhua]
    • GoogleMaps: PHP object injection issue with unserialize() fixed [acrylian - Thanks to abdulrahman]
    • html_meta_tags:
      • Fix some pagination URL's missing trailing slash causing invalid canonical URLs. [acrylian]
      • Fix the opengraph thumb for multimedia items [acrylian - Thanks to JesseHC|
    • http_security_headers [acrylian, fretzl]:
      • Fix issue that legacy header X-Frame-Options could not be disabled correctly.
      • Fix wrong option name for X-Frame-Options.
      • Fix frame-ancestors if only allowed hosts are defined.
      • Remove deprecated block-all-mixed-content directive.
    • mobileTheme: Update Mobile_Detect.php library [fretzl]
    • multiple_layouts: Fix image selection on album edit page not saving if no album layout exists, also fixes image layouts not used properly in search results context [acrylian, fretzl]
    • PHPMailer: Update to version 6.7.1 [fretzl]
    • register_user: PHP object injection issue with unserialize() fixed [acrylian - Thanks to abdulrahman]
    • relatied_items: Fixes usage with multi-word tags [bic]
    • sitemap-extended: Fix non modrewrite URLs to alway include "index.php" (except home page) as used on front end [acrylian]
    • slideshow2: Update cycle2 script to be compatible with jQuery versions 3 and up. The update is from https://github.com/thecarnie/cycle2 , a fork of the original cycle2 repository which is not maintained anymore [fretzl]
    • uploader_jQuery: jQuery-File-Upload-10.31.0 update [acrylian]
    • user_expiry: PHP object injection issue with unserialize() fixed [acrylian - Thanks to abdulrahman]
    • zenpage:
      • Object model changes: The Zenpage class methods getTotalArticles() and getTotalNewsPages() have no internal theme context support anymore and only apply to the general Zenpage object. For category objects use the new same named methods of the ZenpageCategory class [acrylian].
      • Fix and generalize guest login for zenpage items [bic]
    • elFinder: Update to 2.1.61 [fretzl]
    • class-video: Update getID3 library to 1.9.22 [fretzl]
    • openstreetmap:
      • Update leaflet.js [fretzl]
      • The theme function printOpenStreetMap() is deprecated, use the static class method openStreetMap::printOpenStreetMap() instead [acrylian]
    • uploader_jQuery: Update to 10.32.0 [fretzl]


    • Argentinian Spanish (guirala)
    • Dutch (fretzl)
    • German (acrylian)
    • Italian (bic)
    • Simplified Chinese (henrysting)
    • Spanish (guirala)

    Core changes I: General changes

    These changes should not affect you if you use Zenphoto's standard functionality. Certain third party or custom code may require maintenance.

    Deprecation handling changed

    Previously these were handled by the plugin of the same name. Functions had to be copied to it and plugins or themes could provide a deprecated-functions.php file. This was rather inconvenient causing extra work and didn't really work with deprecated class methods. [acrylian, fretzl]

    • The plugin still covers deprecated functions that were copied to it until 1.5.9 but is itself deprecated now.
      • You cannot reliably search for deprecated usages via the plugin due to the changes (except for those the plugin still handles). If you are developing pay attention to the debug log and use a proper code editor or IDE that highlights deprecated functions.
    • From 1.6. on however, deprecated functions instead stay in their place until they are removed. The notice itself is handled by a function deprecationNotice() and now deprecation warnings are issues as E_USER_DEPRECAED.
    • Complete deprecated class or function set files are moved to zp-core/deprecated/.
    • Individual deprecated function notices cannot be disabled anymore, instead they should be fixed. You can still disable all legacy deprecations handled by the plugin by disabling the plugin.

    New folder organization

    We have moved some file categories to their own zp-core subfolders now:

    • class-*.php files -> /classes
    • functions-*.php files -> /functions

    Various text files like templates for the config, htaccess and other files -> /file-templates

    Also, almost all 3rd party libraries have been renanemd from like lib-*.php to follow file naming conventions like those above. They also now are within the /libs folder.

    You should not notice these changes unless you created custom code or are using outdated third party tools calling these directly. This is also directly related to the class filen changes documented below.

    Class name changes and separation into individual files

    These files have been removed and their contained classes moved to individual files (see below):

    • lib-auth.php
    • classes.php

    Classes that shared one file have been moved to individual files:

    • class-authority.php (formerly included in lib-auth.php which now has been removed)
    • class-administrator.php (formerly included in lib-auth.php which now has been removed)
    • class-transientimage.php (formerly part of class-image.php)
    • class-albumbase.php (formerly part of class-album.php)
    • class-dynamicalbum.php (formerly part of class-album.php)
    • class-zpmutex (formerly part of functions-basic.php)
    • class-_zp_html_cache.php (formerly part of functions.php)
    • class-_zp_captcha.php (formerly part of functions.php)

    The authorization class names have been changed:

    • Zenphoto_Authority –> Authority
    • Zenphoto_Administrator –> Administrator

    The old classes exist as child classes in the same file as a temporary fallback.There is only a general deprecation notice if the class object is created using the old class but not if static methods are used directly. The fallback will be removed with the next major update.The usual global authorization and user variables have not been changed. But if you have used the classes in custom code or use any custom authorization via /plugins/alt/lib-auth.php (the doc is now within the file auth.php) you need to update the class names.

    Renamed core files

    Several core files have been renamed to follow our consistent coding guidelines. Normally you don't use these directly but if you somehow do in custom code, you need to change this. There is no fallback.

    • class-search.php –> class-searchengine.php (to match the file name with the class name)
    • auth_zp.php –> auth.php
    • external_auth.php –> class-external_auth.php (this file is actually not actively used by the official Zenphoto release itself)
    • rewrite.php –> functions-rewrite.php
    • reconfigure.php –> functions-reconfigure.php

    Some JS files also have been renamed:

    • admin.js –> zp_admin.js
    • zenphoto.js –> zp_general.js
    • upload.js –> zp_upload.js

    Renamed core folders

    The default error images (err-*.png) have been relocated from /zp-core/images to their own /zp-core/images_errors folder.If you want to override these you have to place your replacements within an /images_errors folder within /plugins for a global override or within your theme's folder. There is no fallback for the previous /images folder.

    Core changes  II: New core classes

    Classes for database handlers and new global variable

    The former procedural functions for the database handling have been deprecated in favor of a much better organized class setup. The following files have been removed:

    • functions-db-MySQLi.php
    • functions-db-PDO_MySQ.php
    • functions-db_NULL.php

    These have been replaced by these classes:

    • class-dbbase.php: This is the parent class and is always loaded even if no database handler is available
    • class-dbmysqli.php: The class used if mysqli is selected as a handler. A child class of dbBase.
    • class-dbpdo_mysql.php: The class used if pdo is selected as a handler. A child class of dbBase.

    If you used database functions in custom code you need to update them to use the new $_zp_db global variable which holds the databsae handler object. Note that the class method names have been aligned to our general naming conventions.

    The MySQL database handler has been removed as it is not part of PHP 7+ anymore. If still configured in older config files setup will try to use MySQLi instead.

    Example: query_full_array() => $_zp_db->queryFullArray()

    You can review the naming changes in the now deprecated functions set to update your code:

    • functions-db.php

    Classes for graphics handlers and new global variable

    The former procedural functions for the database handling have been deprecated in favor of a much better organized class setup. The following files have been removed:

    • lib-NoGraphics.php
    • lib-GD.php
    • lib-Imagick.php

    These have been replaced by these classes:

    • class-graphicsbase.php: This is the parent class and is always loaded even if no graphics handler is available.
    • class-graphicsgd.php: The class used if the GD library is selected as a handler. A child class of graphicsBase.
    • class-graphicsimagick.php: The class used if the Imagick library is selected as a handler. A child class of graphicsBase.

    If you used graphics functions in custom code you need to update it to use the new $_zp_graphics global object variable which holds the graphics handler object:

    Example: zp_createImage() => $_zp_graphics->createImage();

    Other than with the datbase handler change above the overall function names stay the same except that the name prefix "zp_" has been removed. You can review the changes in the now deprecated function set:

    • functions-graphics.php

    MimeTypes library now a class

    The file name of this library has changed and it has been changed from procedural functions into a static class:

    • lib-MimeTypes.php –> class-mimetypes.php:
      • The former function getMimeType() has been deprecated, use mimeType::getType() instead.
      • The former global variable $mime_types has been removed without replacement. Use the static class property mimeType::$mime_types instead. You may need to include the class manually before doing so.
      • You may need to require_once the class manually as you did with the old library as it is not included by default currently.

    Core changes IV: Various internal changes

    Single former procedural functions moved to classes

    The former procedural functions have been deprecated and moved to their related classes as static methods for better code organisation (you will see more of this in the future). Use them as follows now:

    • newImage() –> Image::newImage()
    • newAlbum() –> AlbumBase::newAlbum()
    • search_quote() –> SearchEngine::getSearchQuote()
    • getSearchURL() –> SearchEngine::getSearchURL()

    There are some more. Keep an eye on your debug log if you are using custom code.

    New method for main item classes

    A few class methods have been renamed and aligned for simple base usage and deprecates individual methods:

    • Image class: getFilename() is deprecated -> use getName()instead
    • Albumbase class (and descendants): getFolder() and getFilename() are deprecated -> use getName()instead
    • ZenpagePage, ZenpageNews, ZenpageCategory: getTitlelink() and setTitlelink() are deprecated - -> use getName() instead, also setName() is added
    • The methods getShow() and setShow() of all main item classes are deprecated - use getPublished() and setPublished() instead

    Global variable name changes

    Several global variables have been aligned to follow our own coding guidelines. Most are used internally so you most likely never encounter them. The following variables have been renamed to be all lowercase and with a consistent $_zp prefix.

    Note: There is no fallback or deprecation warning. Normally you should not notice any difference. But if you used them in custom code you need to update your code.


    • $_zp_albumHandlers –> $_zp_album_handlers
    • $_zp_cachefileSuffix –> $_zp_cachefile_suffix (graphic handling)
    • $_locale_Subdomains –> $_zp_locale_subdomains (i18n functionality)
    • $_zp_UTF8 –> $_zp_utf8
    • $_zp_admin_LC_taglist –> $_zp_admin_lc_taglist
    • $_EnabledPlugins –> $_zp_enabled_plugins
    • $_configMutex –> $_zp_mutex
    • $zp_request –> $_zp_request
    • $_set_theme_album -> $_zp_set_theme_album
    • $_user_tags –> $_zp_user_tags
    • $_style_tags –> $_zp_style_tags
    • $_default_tags –> $_zp_default_tags
    • $_common_locale_type –> $_zp_common_locale_type
    • $_common_truncate_handler–> $_zp_common_truncate_handler

    Admin only

    • $zenphoto_tabs –> $_zp_admin_menu
    • $subtabs –> $_zp_admin_submenu
    • $_zp_admin_tab –> $_zp_admin_current_page
    • $_zp_admin_subtab –> $_zp_admin_current_subpage

    Since plugins may use these to define menu entries there is a rough fallback in place that issues a deprecation warning. However, menu entries using the old globals will be appended at the end of the menu. So best is to update your code. The fallback will be removed in 2.0+.

    Other renamed admin globals:

    • $mcr_albumlist –> $_zp_admin_mcr_albumlist
    • $main_tab_space –> $_zp_admin_maintab_space
    • $album_nesting –> $_zp_admin_album_nesting
    • $subalbum_nesting –> $_zp_admin_subalbum_nesting
    • $imagesTab_imageCount –> $_zp_admin_imagestab_imagecount
    • $_zp_adminJS_loaded -> $_zp_adminjs_loaded


    • $_zp_HTML_cache –> $_zp_html_cache (static_html_cache plugin)
    • $_zp_RTL_css –> $_zp_rtl_css (if you use custom tinyMCE config files you have to adjust this) (core, primary for tinymce)
    • $_zp_newsCache –> $_zp_news_cache (zenpage plugin)
    • $_myFavorites –> $_zp_myfavorites (favoriteshandler plugin)
    • $_myFavorites_button_count –> $_zp_myfavorites_button_count (favoriteshandler plugin)
    • $_menu_manager_items –> $_zp_menu_manager_items (menu_manager plugin)
    • $_recursion_limiter –> $_zp_albummenu_recursion_limiter (print_album_menu plugin)
    • $_showNotLoggedin_real_auth –> $_zp_show_not_loggedin_realauth (show_not_logged_in and themeswitcher plugins)
    • $_sitemap_number –> $_zp_sitemap_number (sitemap-extended plugin)
    • $_themeSwitcherThemeList –> $_zp_themeswitcher_themelist (themeswitcher plugin)
    • $__redirect -–> $_zp_userlogin_redirect (user_login_out plugin)
    • $slideshow_instance –> $_zp_slideshow_instance (slideshow2 plugin)
    • $defaultSize –> $_zp_downloadlist_defaultsize (downloadlist plugin)


    • $_oneImagePage –> $_zp_one_image_page (if you use a customized version of the Garland theme you will have to adjust this)

    Global variables removed

    • $_firstPageImages: Album and searchengine objects have a method getFirstPageImages() as a replacement because of the new thumb transition page handling. There is also a template function wrapper of the same name.
    • $_zp_DB_connection: Use $_zp_db->connect() instead.

    For questions and comments please use the forum or discuss on the social networks.

    Related items