Zenphoto 1.6.1

Contributors:

This is a bugfix and very minor security release.

Requirements

Although it should work with PHP 7 as well, we primiarily develop and focus on PHP 8.2 and strongely recommend PHP 8 as a minimum, We could not yet test the new PHP 8.3 but given the documented change it probably should be generally compatible.

Security

Sadly we got a security report via a public GitHub ticket https://github.com/zenphoto/zenphoto/issues/1391 and we also discovered by accident that prior to this the issues had already been reported on various security sites for a few days. This is not responsible behaviour. 

However, we consider both issues not really serious since both require access to the backend. Let us shortly address these issues:

First issue

iFrame usage is quite common, e.g. for Youtube and other services, and as far as we can see there is no general way to do this except by blocking all by default. We don't do this as we don't know what you like to do with your site. If you have more users apart from yourself on your site and are concered about embeds from unwanted sources, configure the security headers plugin accordingly. Additionally you can remove iframe tags from the allowed tags option to completely disallow them.

Second issue

This is a plain backend issue about exporting user data following GDPR requirements. Since only admins or the user himself has rights to do these exports it will only affect those.

General changes and fixes

Localized dates

Because of the strftime() deprecation of PHP 8.1+ we introduced new date format handling. While the conversion of the old deprecated strftime format to standard datetime format generally works, things are more complicated with localized dates (e.g. auto translated day and month names). The normal date functions cannot handle these so a special core PHP class needs to be used. Sadly this requires yet another date format named ICU. The conversion from standard datetime to ICU often fails and results in wrong dates. Reason is partly because the same characters are used for both but with different meaning and also a different way of escaping "normal letters" (leading backslash vs quotes) that is not easily converted. We decided it is not worth the overhead and time as it specifially only affects a few dates and custom dates. Therefore we now have divided this technically:

  • If available on the server systems PHP, the backend date options now have a checkbox for localized dates. It is off by default. We provide an internal catalogue for both datetime and ICU formats for the standard formats in the selector. But for custom date formats you have to provide the proper datetime or ICU format, depending on the checkbox option being enabled or not. 
  • zpFormattedDate() now also has a parameter to enable this for custom date formats. Here you also have to provide ICU instead of datetime formats if you enable it. That internally uses getFormattedLocalizedDate() which was introduced in 1.6 and now only provides localized dates.
  • Fixes wrong months on date archives.

Image processing I: Exif rotation & flipping

  • Fix partly broken automatic image rotation/flipping of thumbs and sized images [acrylian, fretzl]
  • The separated rotation radioboxes and the new 1.6 flipping radioboxes have been joined into one selector on the image edit pages. The purpose is to fix images that are incorrectly rotated or flipped according to their EXIF metadata or the lack thereof. While the rotation radioboxes only set the correct rotation value in the database, the new flipping actually modified the original image. The new selector now consistently only sets the rotation value covering the 1-8 orientation EXIF standard without modifying the original image. [acrylian]
  • The return value is now either false or an array with the rotation in degrees (now clockwise as the EXIF standard documents, to avoid confusion, GD handles the conversion internally) and flipping setting. See the in-file-documentation of the function. [acrylian, fretzl]

Image processing II

  • Image cache files that already have the requested size or are smaller are normally not cached as duplicates. Instead – if your server supports it – normal symlinks are created. For better portablily on site migrations or if space is not a concern, symlinks can now be disabled [acrylian]
  • Cached image files are now correctly covered on copy/move/rename/delete actions of images and albums. If moving individual images, symlinks are updated.
    Note: If moving or copying an album the whole folder is processed so symlinks of cached images are not fixed, instead the  [acrylian]
  • Fix regenerating cached images with ambiguous suffix [bic]
  • Fix wrong generated/missing width/height attributes in printCustomSizeImage() [bic, acyrian]
  • Add default values to several $alt and $size arguments on custom size image functions as there are usages where they may not really be required. Also useful for PHP 8+ named arguments.[acyrian, bic]
  • Fix various variable type issues in exif library  [FilippoBoscarino, kochs-online]
  • Fix GD library unsharp mask issue that could result in an endless loop because of wrong internal calculation [bic-ed]
  • Fix Imagick library creating images with watermarks in color if set to grayscale [acrylian – Thanks to JesseHC)

Item visibility

Sub-items actually do inherit unpublished or password protection status by their parents but this was not consistently covered everywhere so they may have been displayed unwantedly.

Also it was not conistent which password protected items were shown. For example, search results listed password protected albums if published but not Zenpage articles or pages. Some menus listed password protected items, too.

The new consistent behaviour is now that items are listed

  • Logged in:
    • Items the user has the rights level for
    • Items the user has management assignments to
  • Logged out (normal visitor):
    • Items that are published and have no unpublished parent.
    • Password protected items that itself are protected and published but not by any parent. Sub-items are considered protected content.

You may still be able to access any unpublished item by URL if you know it and of course for password protected subitems there will be a password form.
There is a new method isVisible() for all item objects (albums, imges and Zenpage news, articles, categories) to make this check simpler combining checks of several more specifc methods. Generally all methods for getting these objects now follow this behaviour unless any of the parameter available to override is set.

The backend now has new icons for inherited protection and unpublished status. Single admin edit pages now also notify about the status.

The private gallery setting (gallery means the whole site in Zenphoto terms, not just albums!) is also affected. If you set the site to private the whole site requires a password, it is not possible to set an unprotected Zenpage page as the entry page becuase making the site private (protected) protects all of its content.

  • Fix searchfield conflict that made the standard custom field "city" unsearchable [acrylian, fretzl – Special thanks to madman]
  • For 1.6 the search URL was changed to use ?search= for search queries. Since it was easily to be confused with "search" meaning the page in code it has now been changed to ?s=. You should not notice any difference especially for dynamic albums as even those generated before 1.6 are still compatible [acrylian, Thanks to bic]
    • Dynamic albums have word= stored within their .alb files as always. But the values saved within the database are converted to s=. However if existing search= from 1.6. should also still work.
  • Fix frontend search field selector [acrylian]
  • New option to disable the search fields selector added. Previously it had to be hidden via CSS [acrylian]
  • Search results now consistently show password protected but published Zenpage articles, pages and albums if they are toplevel items. Formerly only articles were listed [acrylian, fretzl, bic]

Logs

  • Re-organization of the logs admin page with main log type tabs and a logfile selector and auto scrolling to the latest entry [acrylian]
  • There is now a new option to enable daily logs instead of one large one. If enabled a YYYY-mm-dd date string is appended. If the size is exceeded they are numbered as before [acrylian]
  • Debuglog functions debugLog(), debuglogVar() and debuglogBacktrace() now allow logging into custom log files via new parameter [acrylian] 

Other

  • Various smaller fixes for PHP 8/8.2 [acrylian, fretzl]
  • Fix Content Security Policy warning caused by the uploader_jQuery plugin [fretzl]
  • General reworking of PHP docblock @package tags for automatic documentation generation [acrylian]
  • (Possible) fix for display_errors setting being ignored on setup [Thanks to hazarjast]
  • Fixed manual definition of WEBPATH and SERVERPATH via config file [acrylian]
  • Update jQuery to 3.7.0 and jQuery Migrate to 3.4.1 [fretzl]
  • "https_admin" called "secure admin" server protocol option variant removed as a site should be either https (prefered nowadays!) or http. Especially if the server is configured correctly a mixed usage should not even be possible for security reasons and SEO sake. If you set "https_admin" it will be converted to "https" via setup respectively on reading the value from the config file [acrylian]
  • Valid $ signs in MySQL passwords are now escaped and don't break connection [acrylian - Thanks to ember1205]
  • The backend CSS files have been re-organized within /zp-core/css/. Third party tools that reference these will have to update their links. [acrylian]
  • Image and album classes (and any child) now have the methods to check if they inherit protection or unpublished status by any parent:
    • isUnpublishedByParent() (this includes scheduled publishing)
    • isProtectedByParent()
  • Using the metadatat refresh buttons on the backend now triggers a confirmation warning dialog because using a refresh will re-import and overwrite existing data. Also a note has been added to Options > Image > Metadata [acrylian, fretzl]

Themes

  • All included themes now correctly register the images sizes they use to the cacheManager [fretzl – Thanks to JesseHC]

Plugins

  • cacheManager: This is now the image cache manager it always was.
    • Sidecar images of non image types (video thumbs etc) are now also properly cached [acrylian – Thanks to JesseHC]
    • Cache clearing utility for RSS and HTML cache have been moved to their actual plugins. Search cache clearing is now a standalone utility. [acrylian]
    • Custom size adding/editing option has been removed as these don't make sense if not used in code anywhere. If they are they should be registered via the plugin or theme they belong to. The central button to clear outdated sizes now only keeps those from existing themes and plugins (active nor not) [acrylian]
  • flag_thumbnail: Option to disable default inline styles and individual classes for each flag type so styles can be customized via themes [acrylian]
  • html_meta_tags:
    • if the robots meta element is enabled, unpublished images, albums, articles, categories and pages are set to noindex,nofollow. [acrylian]
    • New robots directives "noai,noimageai" added which at least a few AI scraping bots are said to follow [acrylian]
  • matomo:
    • Improve display of Matomo widget on the backend [fretzl]
    • Update opt-out form to use new script instead of iFrame [acylian]
  • menu_manager:
    • Fix menu_manager not automatically creating a menu set (with createMenuIfNotExists() function) when certain items types are used.[fretzl, acrylian]
    • Custom links now have an option to open in a new tab [acrylian]
    • Menu items are assigned the class "has_password" if the real item represented is password protected [acrylian]
    • Menu items are hidden if the real item represented is not public or if they are sub-items of a protected item being considered as protected content. This naturally overrides the menu item publish state [acrylian]
  • openStreetMap: leafletjs 1.9.3 [acrylian]
  • PHPMailer: PHPMailer 6.9.1 [fretzl]
  • print_album_menu: Password protected albums now correctly get the "has_password" class assigned [bic, acrylian]
  • RSS:
    • Now provides the utility button for clearing the cache and options if the cache should be cleared on publishing items (moved from cachceManager) [acrylian|
    • Various fixes to links, especially the Zenpage pages feed [bic, acrylian]
  • sitemap-extended:
    • Fixed wrong date format used [acrylian – Thanks to JesseHC]
    • Fix listing of first newsindex and category pages if there are no articles at all [acrylian, fretzl]
  • static_html_cache: Now provides the utility button for clearing the cache and options if the cache should be cleared on publishing items (moved from cachceManager) [acrylian|
  • tinymce4: Add TinyMCE options for text color and text background color in the "full" configs for Zenphoto and Zenpage [fretzl]
  • uploader-jquery: Uploading zip files with valid file formats does not thrown an error anymore. [acrylian]
  • video-class: Add better support and handling for video & audio posters  [acrylian – Thanks to JesseHC]
    • Posters now follow the aspect ratio of video player width/height.
    • Posters can be cropped or uncropped maxspace images. Default inline CSS added for proper display.
  • xmpMetadata: Option added to disable exporting multilingual content to XMP files [acrylian]
  • zenpage:
    • ZenpageNews class method isProtected() returns true if the article is in any protected category instead of protected categories only. It is protected in either way so this was misleading and not matching other objects behaviour. Use the other method inProtectedCategory() to check that. [acrylian]
    • ZenpageNews, ZenpageCategory and ZenpagePage classes now have the methods to check if they inherit protection or unpublished status by any parent [acrylian]
      • isUnpublishedByParent() (this includes scheduled publishing): Of course articles have no parents so their classes have this for alignment with the others only.
      • isProtectedByParent(): Retuns true if the articles is in a protected category which acts as the "parent".
    •  Password protected items in the category or pages menu are assigned the class "has_password" [acrylian]
    • Menu items are hidden if not public or if they are sub items of a protected item being considered as protected content. [acrylian]
    • Small restructuring moving classes to a sub folder [acrylian]
    • Fixes for category + date archive selectors on the news articles admin page so they now work properly in combination. Zenpage/ZenpageCategory::getArticles() method now also can request date archives via parameter directly outside the global date archive context and even disable it.

Deprecated plugins

The plugin functionality will generally be kept but restructured, reworked, possibly renamed and moved to core in the future

  • phpMailer
  • zenphoto-sendmail
  • class-AnyFile
  • class-video
  • fieldExtender (actually a tool and not a real plugin)

These plugins will be removed without replacement:

  • ipBlocker: Use more efficient server side blocking via htaccess or similar that does not even reach the site.

Translations

  • Argentinian Spanish (guirala)
  • Dutch (fretzl)
  • German (acrylian)
  • Italian (bic)
  • Japanese (momo-i)
  • Spanish (guirala)

 

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

Related items