diff --git a/plugins/staticpages/functions.inc b/plugins/staticpages/functions.inc index b5c22cd87..0c8178df2 100755 --- a/plugins/staticpages/functions.inc +++ b/plugins/staticpages/functions.inc @@ -329,7 +329,7 @@ function SP_countVisiblePages() */ function SP_displayPage($page, $A, $comment_order = 'ASC', $comment_mode = 'nested', $comment_page = 1, $msg = 0, $query = '') { - global $_CONF, $_TABLES, $_USER, $LANG01, $LANG11, $LANG_STATIC, $_IMAGE_TYPE, $_SP_CONF, $_STRUCT_DATA; + global $_CONF, $_TABLES, $_USER, $LANG01, $LANG11, $LANG_STATIC, $_IMAGE_TYPE, $_SP_CONF; $retval = ''; @@ -573,18 +573,6 @@ function SP_displayPage($page, $A, $comment_order = 'ASC', $comment_mode = 'nest if (!$_SP_CONF['disable_breadcrumbs_staticpages']) { $breadcrumbs = TOPIC_breadcrumbs('staticpages', $page); } - - - $properties['headline'] = $A['sp_title']; - $properties['url'] = $sp_url; - $properties['datePublished'] = $A['created']; - $properties['dateModified'] = $A['modified']; - $properties['description'] = $A['meta_description']; - $properties['keywords'] = $A['meta_keywords']; - $properties['commentCount'] = CMT_commentCount($page, 'staticpages'); - $_STRUCT_DATA->add_type('staticpages', $page, $A['structured_data_type'], $properties); - $_STRUCT_DATA->set_author_item('staticpages', $page, $author_name); - $retval = COM_createHTMLDocument($retval, array('what' => $what, 'pagetitle' => $page_title, 'breadcrumbs' => $breadcrumbs, 'headercode' => $headerCode, 'rightblock' => $rightblock)); } @@ -1891,28 +1879,53 @@ function plugin_getListField_staticpages($fieldname, $fieldvalue, $A, $icon_arr) * @param string $modified Last modified date of page * @return string rendered content (HTML) */ -function SP_render_content($sp_id, $sp_title, $sp_content, $sp_php, $cache_time = 0, $template_id = '', $created = '', $modified = '') +//function SP_render_content($sp_id, $sp_title, $sp_content, $sp_php, $cache_time = 0, $template_id = '', $created = '', $modified = '') +function SP_render_content($A) { - global $_SP_CONF, $LANG_STATIC; + global $_CONF, $_SP_CONF, $LANG_STATIC, $_STRUCT_DATA; $retval = ''; + + $sp_id = $A['sp_id']; + $sp_url = COM_buildURL($_CONF['site_url'] . '/staticpages/index.php?page=' . $sp_id); + $sp_content = $A['sp_content']; + $sp_php = $A['sp_php']; + $cache_time = $A['cache_time']; + $template_id = $A['template_id']; // Retrieve non php staticpage from cache if ($cache_time > -1 && $sp_php == 0) { + $cache_found = false; + // Don't need to cache per theme since not rendered in a block yet $cacheInstance = 'staticpage__' . $sp_id . '__' . CACHE_security_hash(); $retval = CACHE_check_instance($cacheInstance); if ($retval && $cache_time == -1) { - return $retval; + $cache_found = true; } elseif ($retval && $cache_time > 0) { $lu = CACHE_get_instance_update($cacheInstance); $now = time(); if (($now - $lu) < $cache_time) { - return $retval; + $cache_found = true; } else { $retval = ''; } } + + // Now find structured data cache if required + // Structured Data is cached by itself. Need to cache in case structured data autotags exist in page. + // Since autotags are executed when the page is rendered therefore we have to cache structred data if page is cached. + if ($A['structured_data_type'] > 0 && $cache_found) { + if (!$_STRUCT_DATA->get_cachedScript('staticpages', $sp_id, $cache_time)) { + // Structured Data missing for some reason even though page cache found. Render all again + $retval = ''; + } else { + return $retval; + } + } elseif ($cache_found) { + return $retval; + } + } // See if uses template, if so get it @@ -1955,12 +1968,12 @@ function SP_render_content($sp_id, $sp_title, $sp_content, $sp_php, $cache_time 'page_view' => $retval['sp_content'], )); - // Staticpage specfic template variables + // Staticpage specific template variables // Set Staticpage Title - $sp_template->set_var('sp_title', stripslashes($sp_title)); + $sp_template->set_var('sp_title', stripslashes($A['sp_title'])); // ISO 8601 dates for created and modified - $sp_template->set_var('sp_created', date('c', strtotime($created))); - $sp_template->set_var('sp_updated', date('c', strtotime($modified))); + $sp_template->set_var('sp_created', date('c', strtotime($A['created']))); + $sp_template->set_var('sp_updated', date('c', strtotime($A['modified']))); // Add all the staticpage variables as template variables now foreach ($tag as $key => $value) { @@ -2003,19 +2016,34 @@ function SP_render_content($sp_id, $sp_title, $sp_content, $sp_php, $cache_time $sp_content = stripslashes($sp_content); - /* + // Since staticpage can be cached and autotags within content may insert structured data properties need to insert it now before cache file is written. - $properties['headline'] = $A['sp_title']; - $properties['url'] = $sp_url; - $properties['datePublished'] = $A['created']; - $properties['dateModified'] = $A['modified']; - $properties['description'] = $A['meta_description']; - $properties['keywords'] = $A['meta_keywords']; - $properties['commentCount'] = CMT_commentCount($page, 'staticpages'); - $_STRUCT_DATA->add_type('staticpages', $page, $A['structured_data_type'], $properties); - $_STRUCT_DATA->set_author_item('staticpages', $page, $author_name); - $sp_content = $_STRUCT_DATA->toScript('staticpages', $page) . $sp_content; - */ + if ($A['structured_data_type'] > 0 ) { + $properties['headline'] = $A['sp_title']; + $properties['url'] = $sp_url; + $properties['datePublished'] = $A['created']; + $properties['dateModified'] = $A['modified']; + $properties['description'] = $A['meta_description']; + $properties['keywords'] = $A['meta_keywords']; + if ($A['commentcode'] >= 0) { + require_once $_CONF['path_system'] . 'lib-comment.php'; + $properties['commentCount'] = CMT_commentCount($sp_id, 'staticpages'); + } + + $attributes['multi_language'] = true; + $attributes['cache'] = true; + $_STRUCT_DATA->add_type('staticpages', $sp_id, $A['structured_data_type'], $properties, $attributes); + $_STRUCT_DATA->set_author_item('staticpages', $sp_id, COM_getDisplayName($A['owner_id'])); + + /* Decided not to included structure data right by page content even though slightly faster. Rather keep all structured data in the head + // Cache structured data results with staticpage cache + if (($cache_time > 0 || $cache_time == -1) && $sp_php == 0) { + $sp_structureddata = $_STRUCT_DATA->toScript('staticpages', $sp_id); + $sp_content = $sp_structureddata . $sp_content; + } + */ + } + if (($cache_time > 0 || $cache_time == -1) && $sp_php == 0) { CACHE_create_instance($cacheInstance, $sp_content); diff --git a/plugins/staticpages/services.inc.php b/plugins/staticpages/services.inc.php index d22e79cd7..ae16375e0 100644 --- a/plugins/staticpages/services.inc.php +++ b/plugins/staticpages/services.inc.php @@ -479,8 +479,8 @@ function service_submit_staticpages($args, &$output, &$svc_msg) $template_id = ''; $sp_onmenu = 0; - $sp_onhits = $_SP_CONF['show_hits']; - $sp_onlastupdate = $_SP_CONF['show_date']; + $sp_onhits = 0; + $sp_onlastupdate = 0; $sp_label = ""; $sp_centerblock = 0; $sp_php = 0; @@ -491,6 +491,7 @@ function service_submit_staticpages($args, &$output, &$svc_msg) $sp_hits = 0; $meta_description = ""; $meta_keywords = ""; + $structured_data_type = 0; } else { // See if it was a template before, if so and option changed, remove use from other pages if (DB_getItem($_TABLES['staticpage'], 'template_flag', "sp_id = '$sp_old_id'") == 1) { @@ -832,7 +833,8 @@ function service_get_staticpages($args, &$output, &$svc_msg) // WE ASSUME $output doesn't have any confidential fields // Generate output now (only if not grabbing a template since template is combined with variables first and then generated) if (!isset($args['template'])) { - $output['sp_content'] = SP_render_content($page, $output['sp_title'], $output['sp_content'], $output['sp_php'], $output['cache_time'], $output['template_id'], $output['created'], $output['modified']); + //$output['sp_content'] = SP_render_content($page, $output['sp_title'], $output['sp_content'], $output['sp_php'], $output['cache_time'], $output['template_id'], $output['created'], $output['modified']); + $output['sp_content'] = SP_render_content($output); } } else { // an error occurred (page not found, access denied, ...) /** @@ -945,10 +947,10 @@ function service_get_staticpages($args, &$output, &$svc_msg) $order = " ORDER BY modified DESC"; $sql = array(); $sql['mysql'] = "SELECT sp_id,sp_title,sp_page_title,sp_content,sp_hits,created,modified,sp_format,meta_description,meta_keywords,template_flag,template_id,draft_flag,owner_id," - . "group_id,perm_owner,perm_group,perm_members,perm_anon,sp_help,sp_php,sp_inblock,cache_time " + . "group_id,perm_owner,perm_group,perm_members,perm_anon,sp_help,sp_php,sp_inblock,cache_time,structured_data_type " . " FROM {$_TABLES['staticpage']}" . $perms . $order . $limit; $sql['pgsql'] = "SELECT sp_id,sp_title,sp_page_title,sp_content,sp_hits,created,modified,sp_format,meta_description,meta_keywords,template_flag,template_id,draft_flag,owner_id," - . "group_id,perm_owner,perm_group,perm_members,perm_anon,sp_help,sp_php,sp_inblock,cache_time " + . "group_id,perm_owner,perm_group,perm_members,perm_anon,sp_help,sp_php,sp_inblock,cache_time,structured_data_type " . "FROM {$_TABLES['staticpage']}" . $perms . $order . $limit; $result = DB_query($sql); @@ -969,10 +971,9 @@ function service_get_staticpages($args, &$output, &$svc_msg) $output_item['id'] = $output_item['sp_id']; $output_item['title'] = $output_item['sp_title']; $output_item['page_title'] = $output_item['sp_page_title']; - //$output_item['category'] = array($output_item['sp_tid']); $output_item['category'] = TOPIC_getTopicIdsForObject('staticpages', $output_item['sp_id']); - //$output_item['content'] = $output_item['sp_content']; - $output['content'] = SP_render_content($output['sp_id'], $output['sp_title'], $output['sp_content'], $output['sp_php'], $output['cache_time'], $output['template_id'], $output_item['created'], $output_item['modified']); + // $output['content'] = SP_render_content($output['sp_id'], $output['sp_title'], $output['sp_content'], $output['sp_php'], $output['cache_time'], $output['template_id'], $output_item['created'], $output_item['modified']); + $output['content'] = SP_render_content($output); $output_item['content_type'] = 'html'; $owner_data = SESS_getUserDataFromId($output_item['owner_id']); diff --git a/system/classes/structureddata.class.php b/system/classes/structureddata.class.php index f21e08150..1b126e6ce 100644 --- a/system/classes/structureddata.class.php +++ b/system/classes/structureddata.class.php @@ -33,8 +33,8 @@ */ class StructuredData { - private $items = array(); + private $attributes = array(); /** * Constructor @@ -42,6 +42,7 @@ class StructuredData public function __construct() { $this->items = array(); + $this->attributes = array(); } /** @@ -50,7 +51,7 @@ public function __construct() * @param string $type Usually the plugin of the content used to create the structured data * @param string $id Id of content */ - public function create_name($type, $id) + private function create_name($type, $id) { // Make sure core components are called the same thing @@ -82,17 +83,20 @@ public function create_name($type, $id) * @param string $type Plugin of the content used to create the structured data * @param string $id Id of content * @param numeric $sd_type Id of Structured Data Type. See $LANG_structureddatatypes language variable for full list - * @param string $properties Properties for structured data type + * @param string $properties Properties for structured data type (type, headline, url, datePublished, dateModified, commentCount, keywords, description) + * @param string $attributes Attributes for structured data item (cache,) */ - - public function add_type($type, $id, $sd_type, $properties = array()) + public function add_type($type, $id, $sd_type, $properties = array(), $attributes = array()) { - global $_CONF; // Create structured data name $sd_name = $this->create_name($type, $id); + if (isset($attributes['cache']) && $attributes['cache']) { + $this->attributes[$sd_name]['cache'] = true; + } + // Remove any empty properties foreach($properties as $key => $value) { if(empty($value)) @@ -127,7 +131,8 @@ public function add_type($type, $id, $sd_type, $properties = array()) } $lang_id = ''; - if (COM_isMultiLanguageEnabled()) { + // See if item supports Geeklog Multi Language support (ie id of item ends in language type _en) and site Multi Lanugage is enabled + if (isset($attributes['multi_language']) && $attributes['multi_language'] && COM_isMultiLanguageEnabled()) { $lang_id = COM_getLanguageIdForObject($id); } if (empty($lang_id)) { @@ -141,11 +146,6 @@ public function add_type($type, $id, $sd_type, $properties = array()) $this->items[$sd_name]['keywords'] = $properties['keywords']; } - // image - // thumbnailUrl - - // video - // Can be set by autotag which can be executed first so do not overwrite if set if (isset($properties['description']) && !isset($this->items[$sd_name]['description'])) { $this->items[$sd_name]['description'] = $properties['description']; @@ -186,10 +186,8 @@ public function add_type($type, $id, $sd_type, $properties = array()) */ public function set_param_item($type, $id, $name, $value) { - $sd_name = $this->create_name($type, $id); $this->items[$sd_name][$name] = $value; - } /** @@ -201,13 +199,11 @@ public function set_param_item($type, $id, $name, $value) */ public function set_author_item($type, $id, $name) { - $sd_name = $this->create_name($type, $id); $this->items[$sd_name]['author'] = array( "@type" => "Person", "name" => $name ); - } /** @@ -218,7 +214,6 @@ public function set_author_item($type, $id, $name) */ public function set_image_item($type, $id, $url, $width = '', $height = '') { - $sd_name = $this->create_name($type, $id); $image_item = array( "@type" => "ImageObject", @@ -233,7 +228,6 @@ public function set_image_item($type, $id, $url, $width = '', $height = '') } $this->items[$sd_name]['image'][] = $image_item; - } /** @@ -244,38 +238,11 @@ public function set_image_item($type, $id, $url, $width = '', $height = '') */ public function add_BreadcrumbList($type, $id) { - $sd_name = $this->create_name($type, $id); $this->items[$sd_name]['@context'] = "https://schema.org"; $this->items[$sd_name]['@type'] = "BreadcrumbList"; $this->items[$sd_name]['itemListElement'] = array(); - - - /* - $schema['@context'] = "https://schema.org"; - $schema['@type'] = "BreadcrumbList"; - $schema['itemListElement'] = array( - array( - "@type" => "ListItem", - "position" => 1, - "item" => - array( - "@id" => "https://example.com/dresses", - "name" => "Dresses", - ) - ), - array( - "@type" => "ListItem", - "position" => 2, - "item" => - array( - "@id" => "https://example.com/dresses/real", - "name" => "Real Dresses", - ) - ) - ); - echo ''; - */ + } @@ -290,7 +257,6 @@ public function add_BreadcrumbList($type, $id) */ public function set_breadcrumb_item($type, $id, $position, $item_id, $name) { - $sd_name = $this->create_name($type, $id); $this->items[$sd_name]['itemListElement'][] = array( array( @@ -303,10 +269,50 @@ public function set_breadcrumb_item($type, $id, $position, $item_id, $name) ) ) ); - } + /** + * Get Structured Data Cache Instance ID + * + * @param string $sd_name Name of Structured Data item + */ + private function get_cacheInstanceID($sd_name) + { + return 'structureddata__' . $sd_name . '__' . CACHE_security_hash(); + } + /** + * Retrieve a Cached Structured Data item if it exists + * + * @param string $type Plugin of the content used to create the structured data + * @param string $id Id of content + * @param integer $cache_time Cache time of plugin item in seconds. 0 = disabled, -1 is always + */ + public function get_cachedScript($type, $id, $cache_time) + { + $retval = false; + $sd_name = $this->create_name($type, $id); + $cacheInstance = $this->get_cacheInstanceID($sd_name); + //$sd_cache = CACHE_check_instance($cacheInstance); + $sd_cache = CACHE_check_instance($cacheInstance, true, true); // Not language or mobile cache specific (as this is ALL topic information) + if ($sd_cache && $cache_time == -1) { + $item = unserialize($sd_cache); + $this->items[$sd_name] = $item; + + $retval = true; + } elseif ($sd_cache && $cache_time > 0) { + $lu = CACHE_get_instance_update($cacheInstance, true, true); + $now = time(); + if (($now - $lu) < $cache_time) { + $item = unserialize($sd_cache); + $this->items[$sd_name] = $item; + + $retval = true; + } + } + + return $retval; + } /** * Returns JSON-LD script of either 1 or all structured data types. Can be included in head or body of webpage @@ -326,14 +332,23 @@ public function toScript($type = '', $id = '') if (!empty($sd_name)) { // Autotags can insert some structured data variables and may not be setup correctly. Make sure an actual type is set before including if (isset($this->items[$sd_name]['@type'])) { - $script = '' . PHP_EOL; + $script = '' . PHP_EOL; + if (isset($this->attributes[$sd_name]['cache']) && $this->attributes[$sd_name]['cache']) { + $cacheInstance = $this->get_cacheInstanceID($sd_name); + CACHE_create_instance($cacheInstance, serialize($this->items[$sd_name]), true, true); // Not language or mobile cache specific + } + // Since requested then remove from array so not added again later to the head unset($this->items[$sd_name]); } - } else { - foreach ($this->items as $item) { + } else { + foreach ($this->items as $sd_name => $item) { if (isset($item['@type'])) { $script .= '' . PHP_EOL; + if (isset($this->attributes[$sd_name]['cache']) && $this->attributes[$sd_name]['cache']) { + $cacheInstance = $this->get_cacheInstanceID($sd_name); + CACHE_create_instance($cacheInstance, serialize($this->items[$sd_name]), true, true); // Not language or mobile cache specific + } } } }