Plugin Directory

Changeset 2628020


Ignore:
Timestamp:
11/11/2021 10:28:07 AM (4 years ago)
Author:
clearsite
Message:

Import changes from GitHub for version 1.0.16

Location:
branded-social-images/trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • branded-social-images/trunk/info.json

    r2626772 r2628020  
    55  "Author": "Internetbureau Clearsite",
    66  "Author URI": "https://www.clearsite.nl/",
    7   "Version": "1.0.15",
     7  "Version": "1.0.16",
    88  "License": "GPL2"
    99}
  • branded-social-images/trunk/lib/class.og-image-plugin.php

    r2626772 r2628020  
    173173        });
    174174
     175        /**
     176         * url endpoint, the WordPress way
     177         *
     178         * pros:
     179         * 1. it works on non-standard hosts,
     180         * 2. works on nginx hosts
     181         * cons:
     182         * 1. does not work for custom post-type archives
     183         * 2. because it is in essence a page-modifier, WP considers this a page, therefore
     184         * - adds a trailing slash
     185         * - confusing caching plugins into thinking the content-type should be text/html
     186         * 3. the WP construction assumes an /endpoint/value/ set-up, requiring cleanup, see fileter rewrite_rules_array implementation below
     187         *
     188         * Why this way?
     189         *
     190         * Because an .htaccess RewriteRule, although improving performance 20-fold, would be web-server-software specific, blog-set-up specific and multi-site aware
     191         * which makes it quite impossible to do universally. Unfortunately.
     192         *
     193         * If you feel adventurous, you can always add it yourself! It should look something like this:
     194         *
     195         * RewriteRule (.+)/social-image.(jpg|png)/?$ $1/?bsi_img=1 [QSA,L,NC]
     196         *
     197         * If only for a certain domain, you can add a condition;
     198         *
     199         * RewriteCond %{HTTP_HOST} yourdomain.com
     200         * RewriteRule (.+)/social-image.(jpg|png)/?$ $1/?bsi_img=1 [QSA,L,NC]
     201         *
     202         * For more information on apache rewrite rules, see
     203         * @see https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html
     204         */
     205
    175206        add_action('init', function () {
    176207            // does not work in any possible way for Post-Type Archives
     
    193224        });
    194225
    195         add_action('admin_init', function () {
    196             $font_file = get_option(self::DEFAULTS_PREFIX . 'text__font');
    197 
    198             // legacy code follows, todo: investigate removal.
    199             if (preg_match('/google:(.+)/', $font_file, $m)) {
    200                 $defaults = Admin::base_settings();
    201                 $this->text_options = $defaults['text_options'];
    202                 $this->text_options['font-file'] = $font_file;
    203                 $this->text_options['font-family'] = $font_file;
    204                 $this->expand_text_options();
    205                 if ($this->text_options['font-file'] && is_file($this->text_options['font-file']) && $this->text_options['font-file'] !== $font_file) { // PROCESSED!
    206                     update_option(self::DEFAULTS_PREFIX . 'text__font', basename($this->text_options['font-file']));
    207                     wp_redirect(remove_query_arg(''));
    208                     exit;
    209                 }
    210             }
    211         });
     226        // todo: remove in 1.0.20 release
     227//      add_action('admin_init', function () {
     228//          $font_file = get_option(self::DEFAULTS_PREFIX . 'text__font');
     229//
     230//          // legacy code follows, todo: investigate removal.
     231//          if (preg_match('/google:(.+)/', $font_file, $m)) {
     232//              $defaults = Admin::base_settings();
     233//              $this->text_options = $defaults['text_options'];
     234//              $this->text_options['font-file'] = $font_file;
     235//              $this->text_options['font-family'] = $font_file;
     236//              $this->expand_text_options();
     237//              if ($this->text_options['font-file'] && is_file($this->text_options['font-file']) && $this->text_options['font-file'] !== $font_file) { // PROCESSED!
     238//                  update_option(self::DEFAULTS_PREFIX . 'text__font', basename($this->text_options['font-file']));
     239//                  wp_redirect(remove_query_arg(''));
     240//                  exit;
     241//              }
     242//          }
     243//      });
    212244
    213245        // this filter is used when a re-save permalink occurs
    214         // it changes the rewrite rules so the endpoint is value-less and more a tag, like 'feed' is for WordPress.
    215246        add_filter('rewrite_rules_array', function ($rules) {
    216247            $new_rules = [];
     
    225256            }
    226257            $rules = array_merge($pt_archives, $rules);
     258           
     259            /**
     260             * changes the rewrite rules so the endpoint is value-less and more a tag, like 'feed' is for WordPress.
     261             */
    227262            foreach ($rules as $source => $target) {
    228263                if (
     
    267302        add_filter('bsi_post_types', [static::class, 'post_types'], ~PHP_INT_MAX, 0);
    268303
     304        /**
     305         * Patch the response to WordPress oembed request
     306         */
    269307        add_filter('oembed_response_data', function ($data, $post) {
    270308            $id = $post->ID;
     
    281319        }, PHP_INT_MAX, 2);
    282320
     321        /**
     322         * Patch SEO by RankMath JD+JSON data
     323         */
    283324        add_filter('rank_math/json_ld', function ($data, $RankMath_schema_jsonld) {
    284325            $id = $RankMath_schema_jsonld->post_id;
     
    297338    }
    298339
     340    /**
     341     * Test if we want a BSI for this post.
     342     * @todo: future version will have to detect archives and categories as well
     343     * @param $post_id
     344     * @return bool
     345     */
    299346    public static function go_for_id($post_id): bool
    300347    {
     
    308355    }
    309356
     357    /**
     358     * Logging function used for debugging.
     359     * When called with ?debug=BSI, an image url produces debug output
     360     * Because some hosts mess with output buffers and/or reverse proxies, this data is not always visible
     361     * so it is stored for viewing in the config panel as well.
     362     * @return array
     363     */
    310364    public static function log(): array
    311365    {
     
    359413    }
    360414
     415    /**
     416     * yes, we are mimicking get_plugin_data here because get_plugin_data is not always available while get_file_data is.
     417     * we could have statically set the version number, but we could forget to update it.
     418     * @return string the version number of the plugin.
     419     */
    361420    public static function get_version()
    362421    {
    363422        static $version;
    364423        if (!$version) {
    365             // yes, we are mimicking get_plugin_data here because get_plugin_data is not always available while get_file_data is.
    366424            $data = get_file_data(BSI_PLUGIN_FILE, ['Version' => 'Version'], 'plugin');
    367425            $version = $data['Version'];
     
    370428    }
    371429
     430    /**
     431     * Retrieves Media-library-item data with a certain size
     432     * A mashup of wp_get_attachment_image_src and wp_get_attachment_metadata
     433     * @param $image_id
     434     * @param string $size
     435     * @return array|false
     436     */
    372437    public static function wp_get_attachment_image_data($image_id, string $size)
    373438    {
    374439        $data = wp_get_attachment_image_src($image_id, $size);
    375440        $meta = wp_get_attachment_metadata($image_id);
    376         $upl = wp_upload_dir();
    377         $upl = $upl['basedir'];
    378         $data[4] = trailingslashit($upl) . $meta['file'];
    379         if (!empty($meta['sizes'][$size]['path'])) {
    380             $data[4] = trailingslashit($upl) . $meta['sizes'][$size]['path'];
    381         }
    382         elseif (!empty($meta['sizes'][$size]['file'])) {
    383             $file = dirname($data[4]) . '/' . $meta['sizes'][$size]['file'];
     441        if (is_array($data) && is_array($meta)) {
     442            $upl = wp_upload_dir();
     443            $upl = $upl['basedir'];
     444            // path to the base image
     445            $file = $base = trailingslashit($upl) . $meta['file'];
     446            Plugin::log(sprintf(' Base image for #%d: %s', $image_id, $base));
     447            if (!empty($meta['sizes'][$size]['path'])) {
     448                // path to the resized image, if it exists
     449                $file = trailingslashit($upl) . $meta['sizes'][$size]['path'];
     450                Plugin::log(sprintf(' Using \'path\' entry: %s with size-name %s', $file, $size));
     451            }
     452            elseif (!empty($meta['sizes'][$size]['file'])) {
     453                // only a new filename is listed, use directory of base.
     454                $file = dirname($base) . '/' . $meta['sizes'][$size]['file'];
     455                Plugin::log(sprintf(' Using \'file\' entry: %s with size-name %s', $file, $size));
     456            }
     457            // check existence of file.
    384458            if (is_file($file)) {
    385459                $data[4] = $file;
     460            }
     461            else {
     462                Plugin::log(' Selected size-specific file does not exist. Please run a thumbnail rebuild.');
     463                if (is_file($base)) {
     464                    $data[4] = $base;
     465                }
     466                else {
     467                    Plugin::log(' Base image also does not exist. THIS IS A PROBLEM!');
     468                }
    386469            }
    387470        }
     
    445528    }
    446529
     530    /**
     531     * Scrape the title from a rendered page.
     532     * This really is an eye-sore and we will replace it with a title-builder in the future.
     533     * @param $post_id
     534     * @return array|mixed
     535     */
    447536    public static function scrape_title_data($post_id)
    448537    {
     
    511600            $output_format = $output_format[0];
    512601        }
    513         if (!in_array($fallback_format, ['png', 'jpg', 'webp'])) {
     602        if (!in_array($fallback_format, ['png', 'jpg', /* 'webp' */])) {
    514603            $fallback_format = 'jpg';
    515604        }
     
    524613    }
    525614
     615    /**
     616     * wrapper for unlink function for proper error handling or at least error-prevention
     617     * @see unlink
     618     *
     619     * @param $path
     620     * @return bool
     621     */
    526622    private static function unlink($path): bool
    527623    {
     
    535631    }
    536632
     633    /**
     634     * wrapper for rmdir function for proper error handling or at least error-prevention
     635     * also clears .DS_Store items (macOS sucks sometimes) before attempting rmdir.
     636     * @see rmdir
     637     *
     638     * @param $path
     639     * @return bool
     640     */
    537641    private static function rmdir($path): bool
    538642    {
     
    549653    }
    550654
     655    /**
     656     * Clear the BSI cache.
     657     * @return bool
     658     */
    551659    public static function purge_cache(): bool
    552660    {
     
    579687    }
    580688
     689    /**
     690     * @param false $destroy_buffer if false; do a nice flush. if true; previous output is destroyed.
     691     */
    581692    public static function no_output_buffers($destroy_buffer = false)
    582693    {
     
    639750                add_filter('wpseo_twitter_image', [static::class, 'overrule_og_image'], PHP_INT_MAX);
    640751
     752                // this is a very intrusive way, but Yoast does not allow overruling the
     753                // image dimensions.
     754                // @todo: investigate the option of always doing it this way. I wanted to prevent it, bus since we cannot
     755                // @todo: perhaps we should always just kill all og:image data from the head and add it ourselves.
    641756                add_action('wpseo_head', [static::class, 'patch_wpseo_head'], ~PHP_INT_MAX);
    642757                add_action('wpseo_head', [static::class, 'patch_wpseo_head'], PHP_INT_MAX);
     
    20782193            }
    20792194        }
    2080 
    2081         self::track('activate', $network_wide);
    20822195    }
    20832196
    20842197    public static function on_deactivation($network_wide)
    20852198    {
    2086         self::track('deactivate', $network_wide);
     2199        global $wpdb;
     2200        Plugin::purge_cache();
     2201        if ($network_wide && function_exists('is_multisite') && is_multisite()) {
     2202            $blog_ids = $wpdb->get_col("SELECT blog_id FROM {$wpdb->base_prefix}blogs");
     2203            foreach ($blog_ids as $blog_id) {
     2204                switch_to_blog($blog_id);
     2205                Plugin::purge_cache();
     2206                restore_current_blog();
     2207            }
     2208        }
    20872209    }
    20882210
    20892211    public static function on_uninstall($network_wide)
    20902212    {
    2091         self::track('uninstall', $network_wide);
    2092     }
    2093 
    2094     private static function track($action, $network_wide = false)
    2095     {
    2096         // tracking disabled for now, we need to find out if this is allowed.
    2097         if (defined('BSI_TRACKING_ENABLED')) {
    2098             // we like to see where our plugin is used so we can provide support more easily
    2099             // note that the only data we collect are plugin name, version and your website URL.
    2100             // also note that we do not care about the response. (blocking:false)
    2101             wp_remote_get('https://wp.clearsite.nl/tracking/' . ($network_wide ? 'network-' : '') . $action . '/' .
    2102                 basename(dirname(__DIR__)) . '/' . Plugin::get_version() . '/' . get_bloginfo('url'),
    2103                 ['blocking' => false]
    2104             );
    2105         }
     2213        // cannot uninstall without deactivation, so we may expect WordPress to call the dectivation hook.
     2214        // no need to do it ourselves.
    21062215    }
    21072216}
  • branded-social-images/trunk/lib/class.og-image.php

    r2626599 r2628020  
    311311        $type = 'none';
    312312
     313        $title = apply_filters('the_title', get_the_title($post_id), $post_id);
     314
    313315        if (Plugin::setting('use_bare_post_title')) {
    314316            $type = 'wordpress';
    315             $text = apply_filters('the_title', get_the_title($post_id), $post_id);
     317            $text = $title;
    316318            Plugin::log('Text consideration: WordPress title (bare); ' . $text);
    317319        }
     
    342344            Plugin::log('Text: No text found, using default; ' . $text);
    343345            $type = 'default';
     346        }
     347        if (false !== strpos($text, '{title}')) {
     348            Plugin::log('{title} placeholder stored in database. Replacing with actual title.');
     349            Plugin::log(' This is a failsafe, should not happen. Please check the editor javascript console.');
     350            $text = str_replace('{title}', $title, $text);
    344351        }
    345352
  • branded-social-images/trunk/lib/inc.functions.php

    r2626772 r2628020  
    11<?php
    2 
     2/**
     3 * @since 1.0.15
     4 * Some hosts do not have the mime_content_type function.
     5 * In case it is missing, try alternatives
     6 */
    37if (!function_exists('mime_content_type')) {
    48    function mime_content_type($file) {
     9        /**
     10         * Alternative 1: finfo
     11         * Open a connection to the finfo service and ask for the content-type of the file.
     12         */
    513        static $f;
    614        if (function_exists('finfo_open')) {
     
    1321        }
    1422
     23        /**
     24         * Alternative 2: the WordPress function wp_check_filetype
     25         * Why is this not used always, or as an earlier alternative?
     26         * Because it falls back on detection by extension, which is far less preferable than mime sniffing
     27         * And because it might not exist when we need it. (many parts of WordPress are not available during bootstrap or on front-end)
     28         */
    1529        if (function_exists('wp_check_filetype')) {
    1630            $d = wp_check_filetype($file, []);
     
    2034        }
    2135
    22         // if all else fails
    23 
     36        /**
     37         * if all else fails;
     38         * Alternative 3: mime type based on file extension.
     39         * Now this is a potential security risk, but if you are that keen on this; please just fix your webserver to properly
     40         * support mime-sniffing on files.
     41         *
     42         * For our purposes, we only need image/jpeg and image/png, but since this function is missing and we are not alone
     43         * in this universe, we need to provide a fairly complete solution.
     44         */
    2445        $mime_types = array(
    2546            'txt' => 'text/plain',
  • branded-social-images/trunk/readme.txt

    r2626772 r2628020  
    44Requires at least: 4.7
    55Tested up to: 5.8.1
    6 Stable tag: 1.0.15
     6Stable tag: 1.0.16
    77Requires PHP: 7.0
    88License: GPLv2 or later
     
    134134== Changelog ==
    135135
     136= 1.0.16 =
     137* fixed: in some cases, the {title} placeholder gets stored in the post-meta and appears in the generated image. This should not happen as the {title} placeholder is replaced while editing.
     138* cleanup: lot of code cleaned up, comments added
     139* removed: some code suggested support for webp output (instead of png or jpg) but as Facebook and LinkedIn (and probably more) platforms do not support webp for og:image, no reason to try to generate it.
     140
    136141= 1.0.15 =
    137142* fixed: some users report "function mime_content_type does not exist". This function should exist and indicates a broken/misconfigured server. To accommodate, fallback functions are in place.
    138143
    139144= 1.0.14 =
     145* warning: Only install this version if your host has the "magic mime" extension properly configured (function mime_content_type exists)
    140146* important change: Switch from PNG output to JPG output. The reason is disk-space usage; the JPG takes only a fraction of the disk space and has practically the same quality. See the FAQ for more information.
    141147* fixed: showing debug information leaves image cache in locked state, preventing (re-)generation of image.
  • branded-social-images/trunk/wp-plugin.php

    r2626772 r2628020  
    66 * Author: Internetbureau Clearsite
    77 * Author URI: https://clearsite.nl/branded-social-images
    8  * Version: 1.0.15
     8 * Version: 1.0.16
    99 * License: GPL2
    1010 */
     
    6060});
    6161
    62 register_activation_hook(__FILE__, [Plugin::class, 'on_activation']);
    63 register_deactivation_hook(__FILE__, [Plugin::class, 'on_deactivation']);
    64 register_uninstall_hook(__FILE__, [Plugin::class, 'on_uninstall']);
     62/**
     63 * plugin activation/deactivation/uninstall hooks
     64 */
     65register_activation_hook(BSI_PLUGIN_FILE, [Plugin::class, 'on_activation']);
     66register_deactivation_hook(BSI_PLUGIN_FILE, [Plugin::class, 'on_deactivation']);
     67register_uninstall_hook(BSI_PLUGIN_FILE, [Plugin::class, 'on_uninstall']);
     68
    6569/**
    6670 * Reference list
Note: See TracChangeset for help on using the changeset viewer.