File: //proc/self/cwd/wp-content/plugins/cornerstone/includes/classes/Services/Assignments.php
<?php
namespace Themeco\Cornerstone\Services;
use Themeco\Cornerstone\Documents\Document;
class Assignments implements Service {
protected $active_content = null;
protected $active_header = null;
protected $active_footer = null;
protected $active_layout = null;
public function setup() {
// Clear assignment cache actions
add_action( 'cs_save_document', [ $this, 'clear_cache_on_save' ] );
add_action( 'cs_delete_document', [ $this, 'clear_cache_on_save' ] );
// Assign active content action override
add_action( 'cs_assign_active_content', [ $this, 'setActiveContentAction' ], 0, 1 );
}
/**
* Set active content action
* for plugins see custom 404
*/
public function setActiveContentAction($id) {
$doc = Document::locate($id);
if (empty($doc)) {
return;
}
$this->setActiveContent($doc);
}
public function setActiveContent($doc) {
$this->active_content = $doc;
}
public function getActiveContent() {
return $this->active_content;
}
public function get_rules( $type ) {
$posts = cornerstone( 'Locator' )->find_posts( [
'post_types' => Document::resolvePostTypeForDocType( $type ),
'post_status' => 'tco-data'
] );
$sets = [];
foreach ($posts as $post ) {
$document = cornerstone('Resolver')->getDocument( $post );
if ($document && $document->getDocType() === $type ) {
$settings = $document->settings();
if (!empty($settings['assignments']) ) {
$sets[] = [
'id' => $document->id(),
'title' => $document->title(),
'rules' => $settings['assignments'],
'priority' => (int) $settings['assignment_priority']
];
}
}
}
usort( $sets, [ $this, 'sort_rules' ]);
return $sets;
}
public function sort_rules( $a, $b ) {
$a_priority = $a['priority'];
$b_priority = $b['priority'];
if ($a_priority == $b_priority) {
// Arrange by id if titles equal
if ($a['title'] === $b['title']) {
return ($a['id'] > $b['id']) ? -1 : 1;
}
// Sort by title if applicable
return ($a['title'] < $b['title'])
? -1
: 1;
}
// Normal Priority arrangement
return ($a_priority < $b_priority) ? -1 : 1;
}
public function getDocLayoutSetting( $type ) {
$settings = $this->active_content->settings();
if ($type === 'layout:single' && isset($settings['layoutSingle'])) {
return $settings['layoutSingle'];
}
if ($type === 'layout:header' && isset($settings['layoutHeader'])) {
return $settings['layoutHeader'];
}
if ($type === 'layout:footer' && isset($settings['layoutFooter'])) {
return $settings['layoutFooter'];
}
return null;
}
public function getFirstMatch($type) {
if ($this->active_content) {
$explicit = $this->getDocLayoutSetting($type);
if ( !empty( $explicit ) && $explicit !== 'default' ) {
return $explicit;
}
}
$rules = $this->getCachedRules( $type );
$matcher = cornerstone('RuleMatching');
foreach ($rules as $set) {
if ($matcher->match( $set['rules'] ) ) {
return $set['id'];
}
}
return null;
}
public function getOptionKey( $type ) {
return str_replace(":", '_', "cs_assignment_cache_$type");
}
public function clear_cached_assignments() {
delete_option( $this->getOptionKey( 'layout:header' ) );
delete_option( $this->getOptionKey( 'layout:footer' ) );
delete_option( $this->getOptionKey( 'layout:single' ) );
delete_option( $this->getOptionKey( 'layout:archive' ) );
delete_option( $this->getOptionKey( 'layout:single-wc' ) );
delete_option( $this->getOptionKey( 'layout:archive-wc' ) );
}
public function clear_cache_on_save( $doc ) {
delete_option( 'x_cache_google_fonts_request' );
if ( strpos( $doc->type(), 'layout' ) === 0 ) {
$this->clear_cached_assignments();
}
}
public function getCachedRules( $type ) {
$option_key = $this->getOptionKey( $type );
$rules = get_option($option_key);
if (false === $rules) {
$rules = $this->get_rules( $type );
add_option($option_key, $rules); // add_option enables use of autoload which is desirable here
}
return $rules;
}
public function get_active_header() {
try {
$assignment = $this->getFirstMatch( 'layout:header' );
if ( $assignment === 'none') {
return null;
}
if ( is_null( $assignment ) ) {
// This filter is useful to provide a fallback for when no conditions match
$assignment = apply_filters( 'cs_locate_header_assignment', null, null, null ); // params deprecated
}
// This filter can be used to force an assignment regardless of what was previously detected
$assignment = apply_filters( 'cs_match_header_assignment', $assignment, null, null ); // params deprecated
if ( ! is_null( $assignment ) ) {
$assigned_document = $this->getAssignedDocument( 'layout:header', (int) $assignment);
if ($assigned_document) {
$this->active_header = $assigned_document;
return $this->active_header;
}
}
} catch( \Exception $e ) {
trigger_error('Unable to load assigned header ' . $e->getMessage(), E_USER_WARNING);
}
return null;
}
public function get_active_footer() {
try {
$assignment = $this->getFirstMatch( 'layout:footer' );
if ( $assignment === 'none') {
return null;
}
if ( is_null( $assignment ) ) {
// This filter is useful to provide a fallback for when no conditions match
$assignment = apply_filters( 'cs_locate_footer_assignment', null, null, null ); // params deprecated
}
// This filter can be used to force an assignment regardless of what was previously detected
$assignment = apply_filters( 'cs_match_footer_assignment', $assignment, null, null ); // params deprecated
if ( ! is_null( $assignment ) ) {
$assigned_document = $this->getAssignedDocument( 'layout:footer', (int) $assignment);
if ($assigned_document) {
$this->active_footer = $assigned_document;
return $this->active_footer;
}
}
} catch( \Exception $e ) {
trigger_error('Unable to load assigned footer. ' . $e->getMessage(), E_USER_WARNING);
}
return null;
}
public function detect_theme_layout_type() {
if (is_singular() || is_404() ) {
return 'layout:single';
}
return 'layout:archive';
}
public function getAssignedDocument( $type, $assignment ) {
// Filters to reassign doc id
list($type, $assignment) = apply_filters("cs_detect_assigned_document", [$type, $assignment]);
$doc = cornerstone('Resolver')->getDocument($assignment);
return $doc && $doc->getDocType() === $type ? $doc : null;
}
public function get_active_layout() {
try {
$layout_type = apply_filters( 'cs_detect_layout_type', $this->detect_theme_layout_type() );
$assignment = $this->getFirstMatch( $layout_type );
// Hook for replacing if hook found
// See PreviewState::getDocTypeHookWithType
$hook_type = str_replace(":", '-', $layout_type );
if (is_null( $assignment ) ) {
// This filter is useful to provide a fallback for when no conditions match
$assignment = apply_filters( 'cs_locate_' . $hook_type . '_assignment', null );
}
// This filter can be used to force an assignment regardless of what was previously detected
$assignment = apply_filters( 'cs_match_' . $hook_type . '_assignment', $assignment );
if ( ! is_null( $assignment ) ) {
$assigned_document = $this->getAssignedDocument( $layout_type, (int) $assignment);
if ($assigned_document) {
$this->active_layout = $assigned_document;
return $this->active_layout;
}
}
} catch( \Exception $e ) {
trigger_error('Unable to load assigned layout. ' . $e->getMessage(), E_USER_WARNING);
}
return null;
}
public function get_last_active_header() {
return isset( $this->active_header ) ? $this->active_header : null;
}
public function get_last_active_footer() {
return isset( $this->active_footer ) ? $this->active_footer : null;
}
public function get_last_active_layout() {
return isset( $this->active_layout ) ? $this->active_layout : null;
}
}