File: //proc/self/cwd/wp-content/plugins/cornerstone/includes/classes/Controllers/Templates.php
<?php
namespace Themeco\Cornerstone\Controllers;
use DomainException;
use Themeco\Cornerstone\Services\Routes;
use Themeco\Cornerstone\Services\Permissions;
use Themeco\Cornerstone\Services\Templates as TemplateService;
use Themeco\Cornerstone\Documents\Document;
use Themeco\Cornerstone\Services\RemoteAssets;
use Themeco\Cornerstone\Templating\Template;
use Themeco\Cornerstone\Util\Endpoint;
class Templates {
private $routes;
private $permissions;
private $templates;
private $remoteAssets;
public function __construct(Routes $routes, Permissions $permissions, TemplateService $templates, RemoteAssets $remoteAssets) {
$this->routes = $routes;
$this->permissions = $permissions;
$this->templates = $templates;
$this->remoteAssets = $remoteAssets;
}
public function setup() {
$this->routes->add_route('get', 'template-index', [$this, 'getAll']);
$this->routes->add_route('get', 'template-item', [$this, 'getItem']);
$this->routes->add_route('get', 'template-item-full', [$this, 'getItemFull']);
$this->routes->add_route('post', 'template-item-create', [$this, 'createItem']);
$this->routes->add_route('post', 'templates-import', [$this, 'import']);
$this->routes->add_route('post', 'templates-dependency', [$this, 'importDependency']);
$this->routes->add_route('post', 'templates-terms', [$this, 'importTerms']);
$this->routes->add_route('post', 'templates-delete', [$this, 'deleteItems']);
$this->routes->add_route('post', 'template-item-update', [$this, 'updateItem'] );
$this->routes->add_route('post', 'templates-menu-import', [$this, 'importMenu'] );
$this->routes->add_route('post', 'template-remote', [$this, 'getRemoteItem']);
}
public function getAll() {
return $this->templates->query();
}
public function _getItem( $params, $full) {
if (! isset($params['id'])) {
throw new \Exception( 'Invalid params' );
}
$template = Template::locate( $params['id'] );
if ( ! $template ) {
throw new \Exception( 'Could not locate template' );
}
if ($full) {
$template->loadMeta();
}
return $template->serialize();;
}
public function getItem( $params ) {
return $this->_getItem( $params, false );
}
public function getItemFull( $params ) {
return $this->_getItem( $params, true );
}
public function locateExistingDependency( $hash ) {
global $wpdb;
$results = $wpdb->get_results( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_cs_import' AND meta_value = %s", $hash ) );
return $results ? Document::locate((int) $results[0]->post_id ): null;
}
public function importTerms( $params ) {
if (
! $this->permissions->userCan('template.manage_library')
&& ! $this->permissions->userCan('template.import_terms')
) {
throw new \Exception( 'Unauthorized' );
}
if ( ! isset( $params['terms'] ) ) {
throw new \Exception( 'Incomplete data' );
}
$result = [];
foreach ($params['terms'] as $hash => $term) {
$existing_term = get_term_by( 'name', $term['name'], $term['taxonomy'] );
if ( $existing_term ) {
$term_id = (int) $existing_term->term_id;
wp_update_term( $term_id, $term['taxonomy'], array(
'description' => $term['description'],
'slug' => $term['slug']
));
$result[$hash] = $term_id;
} else {
$newTerm = wp_insert_term( $term['name'], $term['taxonomy'], array(
'description' => $term['description'],
'slug' => $term['slug']
));
$result[$hash] = (int) $newTerm['term_id'];
}
}
return $result;
}
public function importDependency( $params ) {
if ( ! $this->permissions->userCan('template.manage_library') ) {
throw new \Exception( 'Unauthorized' );
}
if ( ! isset( $params['data'] ) || ! isset( $params['data']['sig']) ) {
throw new \Exception( 'Incomplete data' );
}
$existing = $this->locateExistingDependency( $params['data']['sig'] );
// Found existing signature and that signature is the same type
if ( $existing && $existing->getDocType() === $params['data']['subType']) {
// In case the post is in the trash
// it will put it in limbo without this
wp_untrash_post($existing->id());
$status = $existing->getPublishStatusType();
wp_update_post([
'ID' => $existing->id(),
'post_status' => $status,
]);
$hasSaved = !empty(get_post_meta($existing->id(), '_cs_last_save'));
// Replace content if replace strategy setup
if ( isset( $params['strategy'] ) && $params['strategy'] === 'replace' && !$hasSaved) {
$existing->update([
'elements' => $params['data']['meta']['elements'],
'settings' => $params['data']['meta']['settings']
]);
$existing->save();
}
return $existing->id();
}
$doc = Document::create( $params['data']['subType'] );
$doc->update([
'title' => $params['data']['title'],
'elements' => $params['data']['meta']['elements'],
'settings' => $params['data']['meta']['settings']
]);
$doc->save();
$id = $doc->id();
if ( isset($params['fullSite']) && $params['fullSite'] ) {
if ( isset( $params['data']['page_on_front'] ) ) {
update_option('page_on_front', $id );
}
if ( isset( $params['data']['page_for_posts'] ) ) {
update_option('page_for_posts', $id );
}
}
// Update thumbnail
if ( isset( $params['data']['thumbnail']) ) {
set_post_thumbnail(
$id,
(int)$params['data']['thumbnail']
);
}
if ( isset( $params['data']['terms']) ) {
}
if ( isset( $params['data']['parent']) ) {
}
update_post_meta( $id, '_cs_import', $params['data']['sig'] );
return $id;
}
/**
* Import menu and create nav menu items
*/
public function importMenu($params) {
if ( ! $this->permissions->userCan('template.manage_library') ) {
throw new \Exception( 'Unauthorized' );
}
$menu = cs_get_array_value($params, 'menu', []);
if (empty($menu['name'])) {
throw new DomainException('Invalid menu sent to menu import');
}
// Already has a menu with name
$foundMenus = wp_get_nav_menus([ 'name' => $menu['name'] ]);
if (!empty($foundMenus)) {
$foundMenuID = $foundMenus[0]->term_id;
$this->setMenuAsMain($foundMenuID);
return $foundMenus;
}
// Create initial menu
$created = wp_create_nav_menu($menu['name']);
$this->setMenuAsMain($created);
if (!$created) {
throw new DomainException('Could not create nav menu ' . $menu['name']);
}
// Loop and add new items
foreach ($menu['items'] as $item) {
$this->importMenuItem($created, $item);
}
return $created;
}
/**
* Import menu item entry
*/
public function importMenuItem($created, $item, $parentID = null) {
// Menu item is a post and should grab the new post ID
if ($item['menu-item-object'] !== 'custom') {
$existing = $this->locateExistingDependency( $item['menu-item-object-id'] );
if (empty($existing)) {
trigger_error('Could not locate existing dependency when creating nav menu item ' . $item['menu-item-object-id']);
return;
}
$item['menu-item-object-id'] = $existing->id();
}
$item['menu-item-parent-id'] = $parentID;
// Update nav menu item creating
$menuItemID = wp_update_nav_menu_item($created, 0, $item);
// Import child menu items
if (!empty($item['children'])) {
foreach ($item['children'] as $child) {
$this->importMenuItem($created, $child, $menuItemID);
}
}
}
/**
* Sets a menu as the primary and footer
*/
private function setMenuAsMain($menuID) {
$locations = get_nav_menu_locations();
$locations['menu-header'] = $menuID;
$locations['menu-footer'] = $menuID;
$locations['primary'] = $menuID;
$locations['footer'] = $menuID;
set_theme_mod( 'nav_menu_locations', $locations );
}
public function import($params) {
$save = isset( $params['saveToLibrary'] ) && $params['saveToLibrary'];
$overwrite = !empty($params['overwrite']);
if (
! $this->permissions->userCan('template.manage_library')
&& (
! $save
&& ! $this->permissions->userCan('template.insert')
)
) {
throw new \Exception( 'Unauthorized' );
}
if ( ! isset( $params['items'] ) ) {
throw new \Exception( 'Attempting to create template without items' );
}
$titles = [];
if ($save) {
global $wpdb;
$titles = $wpdb->get_col( "SELECT post_title FROM $wpdb->posts WHERE post_type = 'cs_template'" );
}
$results = [];
foreach ( $params['items'] as $item ) {
if ( ! isset( $item['type'] ) || ! isset( $item['subType'] ) ) {
continue;
}
$record = Template::create($item['type'], $item['subType'], !$save );
if ( isset( $item['title'] ) ) {
if ($save) {
// Overwrite since the title is found
if ($overwrite && in_array( $item['title'], $titles )) {
$titleSanitized = esc_sql($item['title']);
$id = $wpdb->get_col( "SELECT ID FROM $wpdb->posts WHERE post_type = 'cs_template' AND post_title = '$titleSanitized'" );
$id = $id[0];
$item['id'] = $id;
$results[] = $this->updateItem($item);
continue;
}
$original = $item['title'];
$index = 2;
while ( in_array( $item['title'], $titles ) ) {
$item['title'] = str_replace('{{index}}', $index++, str_replace('{{label}}', $original, csi18n('common.indexed')));
}
}
$record->setTitle( $item['title'] );
}
if ( isset( $item['preview'] ) ) {
$record->setPreview( $item['preview'] );
}
if ( isset( $item['meta'] ) ) {
$record->setMeta( $item['meta'] );
}
// Thumbnail sent from a document type
// that is being imported as template
if (isset($item['thumbnail'])) {
$record->setThumbnail( $item['thumbnail'] );
}
if ($save) {
$record->save();
}
$results[] = $record->serializeFull();
}
return [ 'items' => $results ];
}
public function createItem($params) {
if ( ! $this->permissions->userCan('template.manage_library') ) {
throw new \Exception( 'Unauthorized' );
}
if ( ! isset( $params['type'] ) ) {
throw new \Exception( 'Attempting to create template without specifying a type.' );
}
if ( ! isset( $params['subType'] ) ) {
throw new \Exception( 'Attempting to create template without specifying a subtype.' );
}
$record = Template::create($params['type'], $params['subType']);
if ( isset( $params['title'] ) ) {
$record->setTitle( $params['title'] );
}
if ( isset( $params['preview'] ) ) {
$record->setPreview( $params['preview'] );
}
if ( isset( $params['meta'] ) ) {
$record->setMeta( $params['meta'] );
}
return $record->save();
}
public function updateItem( $params ) {
if ( ! $this->permissions->userCan('template.manage_library') ) {
throw new \Exception( 'Unauthorized' );
}
if ( ! isset( $params['id'] ) ) {
throw new \Exception( 'Attempting to update Template without specifying an ID.' );
}
if ( ! $this->permissions->userCan('template.manage_library') ) {
throw new \Exception( 'Unauthorized' );
}
$template = Template::locate( (int) $params['id']);
if ( ! $template ) {
throw new \Exception( 'Invalid template' );
}
if ( isset( $params['title'] ) ) {
$template->setTitle( $params['title'] );
}
if ( isset( $params['preview'] ) ) {
$template->setPreview( $params['preview'] );
}
if ( isset( $params['meta'] ) ) {
$template->setMeta( $params['meta'] );
}
return $template->save();
}
public function deleteItems( $params ) {
if ( ! $this->permissions->userCan('template.manage_library') ) {
throw new \Exception( 'Unauthorized' );
}
if (! isset($params['ids'])) {
throw new \Exception( 'Ids to delete missing' );
}
foreach ( $params['ids'] as $id ) {
$template = Template::locate( (int) $id);
$template->delete();
}
return array( 'success' => true );
}
public function getRemoteItem( $params ) {
if ( ! $this->permissions->userCan('template') ) {
throw new \Exception( 'Unauthorized' );
}
if ( isset($params['site'])) {
$this->remoteAssets->proxyFile( '/site/' . $params['site'] );
}
if ( isset($params['asset'])) {
// Filter and expand if needed
// used by packs
$params['asset'] = apply_filters('cs_remote_asset_path', $params['asset']);
$url = strpos($params['asset'], "http") === 0
? $params['asset']
: "/asset/" . $params['asset'];
$this->remoteAssets->proxyFile($url);
}
throw new \Exception( 'Asset id missing' );
}
// public function export_locate_image_ids( $data ) {
// if ( ! $this->permissions->userCan('template.manage_library') ) {
// throw new \Exception( 'Unauthorized' );
// }
// if ( ! isset( $data['hashMap'] ) ) {
// throw new \Exception( 'Ids to locate missing.' );
// }
// foreach ( $data['hashMap'] as $hash => $source) {
// $img_atts = cs_apply_image_atts( [ 'src' => $source, 'size' => null ]);
// $resolved[$hash] = isset( $img_atts['src'] ) && $img_atts['src'] ? $img_atts['src'] : null;
// }
// return array(
// 'resolved' => $resolved,
// 'success' => true
// );
// }
// protected function find_more_global_blocks( $elements ) {
// $more = array();
// foreach( $elements as $element ) {
// if ( ! isset( $element['_type'] ) ) {
// continue;
// }
// if ( isset( $element['_modules'] ) ) {
// $more = array_merge($more, $this->find_more_global_blocks( $element['_modules']) );
// }
// if ( 'global-block' === $element['_type'] && isset( $element['global_block_id']) ) {
// array_push($more, $element['global_block_id']);
// }
// }
// return array_unique( $more );
// }
// public function import_items( $data ) {
// if ( ! $this->permissions->userCan('template.manage_library') ) {
// throw new \Exception( 'Unauthorized' );
// }
// if ( ! isset( $data['packageSignature'] ) ) {
// throw new \Exception( 'Package signature missing.' );
// }
// if ( ! isset( $data['files'] ) || ! $this->validate_import_files( $data['files'] ) ) {
// throw new \Exception( 'Files failed validation.' );
// }
// $response = [ 'done' => true, 'templates' => [] ];
// foreach ($data['files'] as $file) {
// if ( 'template' === $file['type'] ) {
// $template_data = $file['data'];
// $template_data['package_signature'] = $data['packageSignature'];
// $template = new \Cornerstone_Template( $template_data );
// if ( isset( $data['saveToLibrary'] ) && $data['saveToLibrary'] ) {
// $template->save();
// } else {
// $response['templates'][] = $template->serialize();
// }
// }
// if ( 'global-block' === $file['type'] ) {
// Document::locate((int) $file['data']['id'])->update([
// 'elements' => $file['data']['elements'],
// 'settings' => $file['data']['settings']
// ])->save();
// }
// }
// return $response;
// }
// protected function validate_import_files( $files ) {
// foreach ($files as $file) {
// if ( ! isset( $file['type'] ) ) {
// return false;
// }
// }
// return true;
// }
// public function prepare_global_blocks_import( $data ) {
// if ( ! $this->permissions->userCan('template.manage_library') ) {
// throw new \Exception( 'Unauthorized' );
// }
// $global_blocks = array();
// if ( ! isset( $data['globalBlockRequests'] ) ) {
// throw new \Exception( 'No global blocks' );
// }
// foreach ($data['globalBlockRequests'] as $global_block_request) {
// $global_block = Document::create('custom:global-block-compat')->update([
// 'title' => $global_block_request['title']
// ]);
// $global_block->save();
// $global_blocks[$global_block_request['id']] = $global_block->id();
// }
// return array(
// 'globalBlockIDs' => $global_blocks,
// 'success' => true
// );
// }
}