File: //proc/self/cwd/wp-content/plugins/cornerstone/includes/classes/Services/Templates.php
<?php
namespace Themeco\Cornerstone\Services;
use DomainException;
use Themeco\Cornerstone\Util\Factory;
use Themeco\Cornerstone\Templating\Template;
use Themeco\Cornerstone\Templating\Export;
use Themeco\Cornerstone\Documents\Document;
use Themeco\Cornerstone\Documents\DocumentCache;
use Themeco\Cornerstone\Util\Endpoint;
use Themeco\Cornerstone\Util\Filesystem;
class Templates implements Service {
protected $permissions;
protected $imageImportEndpoint;
protected $exportEndpoint;
protected $exportAllEndpoint;
protected $filesystem;
protected $legacySiteImportEndpoint;
protected $codebaseBridge;
private $routes;
public function __construct(
Permissions $permissions,
Endpoint $imageImportEndpoint,
Endpoint $exportEndpoint,
Endpoint $legacySiteImportEndpoint,
Endpoint $exportAllEndpoint,
Filesystem $filesystem,
CodebaseBridge $codebaseBridge,
Routes $routes
) {
$this->permissions = $permissions;
$this->imageImportEndpoint = $imageImportEndpoint;
$this->exportEndpoint = $exportEndpoint;
$this->exportAllEndpoint = $exportAllEndpoint;
$this->filesystem = $filesystem;
$this->legacySiteImportEndpoint = $legacySiteImportEndpoint;
$this->codebaseBridge = $codebaseBridge;
$this->routes = $routes;
}
public function setup() {
$this->exportEndpoint->config( [
'requestKey' => 'cs-export',
'handler' => [ $this, 'exportHandler' ]
])->start();
$this->legacySiteImportEndpoint->config( [
'requestKey' => 'cs-legacy-site-import',
'handler' => [ $this->codebaseBridge->legacyPlugin()->component('Controller_Design_Cloud'), 'import_site' ]
])->start();
$this->imageImportEndpoint->config( [
'requestKey' => 'cs-upload-image',
'handler' => [ $this, 'imageImportHandler' ]
])->start();
// Export All templates
$this->exportAllEndpoint->config( [
'requestKey' => 'cs-export-all',
'handler' => [ $this, 'exportAllHandler' ]
])->start();
$this->routes->add_route('post', 'export-document', [$this, 'exportDocument']);
add_action( 'init', function() {
register_post_type( 'cs_template', array(
'public' => false,
'exclude_from_search' => false,
'capability_type' => 'page',
'supports' => false,
'labels' => [
'name' => __('Templates', 'cornerstone'),
'singular_name' => __('Template', 'cornerstone'),
]
) );
// Classic Cornerstone templates
register_post_type( 'cs_user_templates', array(
'public' => false,
'capability_type' => 'page',
'supports' => false
));
});
}
public function query( $data = []) {
$args = [
'post_type' => array( 'cs_template', 'cs_user_templates' ), // include old type so it can be accounted for in migration
'post_status' => array( 'tco-data', 'publish' ),
'orderby' => 'title',
'order' => 'ASC',
'posts_per_page' => apply_filters( 'cs_query_limit', 2500 ),
'cs_all_wpml' => true
];
if ( isset( $data['type'] ) ) {
$args['meta_key'] = '_cs_template_identifier';
$args['meta_value'] = $data['type'];
}
$where_filter = null;
if (isset($data['search'])) {
$args['suppress_filters'] = false;
$where_filter = function ($where) use ($data){
// Search by title and post type.
global $wpdb;
$search = '%' .$data['search']. '%';
$where .= $wpdb->prepare(" AND ({$wpdb->posts}.post_title LIKE %s OR {$wpdb->posts}.post_content LIKE %s)", $search,$search);
return $where;
};
add_filter('posts_where', $where_filter);
}
if ( isset( $data['offset'] ) ) {
$args['offset'] = $data['offset'];
}
$posts = get_posts( $args );
if ( $where_filter ) {
remove_action('posts_where', $where_filter);
}
return array_values(array_filter(array_map(function( $post ){
try {
$template = Template::locate( $post );
if ($template) {
return $template->serialize();
}
// Template::locate accounts for user permissions, and also active plugins like WC
// it's possible to have a post in the DB but not allow it as a template
return null;
} catch (\Exception $e) {
trigger_error("Unable to read template data " . $e->getMessage() );
}
},$posts)));
}
public function createExport() {
return Factory::create(Export::class);
}
public function imageImportHandler( $request, $files = [] ) {
if ( ! $this->permissions->userCan('template.manage_library') ) {
throw new \Exception( 'Unauthorized' );
}
// This can take a long time due to image magick processing
set_time_limit(1200);
$list = is_array($request)
? $request
: explode(',', $request->get_param('cs_media_upload_files'));
$result = [];
foreach ($list as $hash) {
try {
global $wpdb;
$results = $wpdb->get_results( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_cs_attachment_import' AND meta_value = %s", $hash ) );
if ( $results ) {
$post_id = $results[0]->post_id;
} else {
//Fix media import issue due to other 3rd party plugins that uses wp_handle_upload_prefilter
global $wp_filter;
unset($wp_filter['wp_handle_upload_prefilter']);
require_once( ABSPATH . 'wp-admin/includes/image.php' );
require_once( ABSPATH . 'wp-admin/includes/file.php' );
require_once( ABSPATH . 'wp-admin/includes/media.php' );
$post_id = null;
if (empty($files[$hash])) {
$post_id = media_handle_upload( 'cs_media_upload_' . $hash, 0, [], [ 'action' => 'wp_handle_upload'] );
} else {
$post_id = $this->addLocalToMediaManager(
$files[$hash]['name'],
$files[$hash]['path']
);
}
if ( is_wp_error( $post_id ) ) {
throw new \Exception( $post_id->get_error_message() . ' ' . $hash);
throw new \Exception( $post_id->get_error_message() );
}
update_post_meta( $post_id, '_cs_attachment_import', $hash );
}
$result[$hash] = [$post_id,wp_get_attachment_url( $post_id )];
} catch( \Exception $e) {
$result[$hash] = [ 'error' => $e->getMessage() ];
}
}
return $result;
}
// Export .tco file (zip) and output it
// via createExport
public function exportHandler($data) {
if ( ! $this->permissions->userCan('template.manage_library') ) {
throw new \Exception( 'Unauthorized' );
}
if ( ! isset( $data['ids'] ) ) {
throw new \Exception('ids not specified');
}
$excludeThumbnails = apply_filters('cs_template_export_exclude_thumbnails', false);
$zip = $this->createExport()
->setOption('excludeThumbnails', $excludeThumbnails)
->add( $data['ids'] )
->organize()
->archive();
if (is_wp_error($zip)) {
throw new \DomainException($zip->get_error_message());
}
$this->filesystem->sendFile($zip);
}
/**
* Export individual document
*
* Uses 'document' group so it adds a new document on another site
*/
public function exportDocument($params) {
if (empty($params['id'])) {
throw new DomainException('Valid id not sent to document export');
}
$zip = $this->createExport()
->setOption('excludeThumbnails', true)
->add( [ $params['id'] ], 'document' )
->organize()
->archive();
if (is_wp_error($zip)) {
throw new \DomainException($zip->get_error_message());
}
return [
'tco' => base64_encode(file_get_contents($zip))
];
}
/**
* Export site handler
*/
public function exportAllHandler($data) {
if (!$this->permissions->userCan('global.export_documents')) {
throw new \Exception( 'Unauthorized' );
}
// Get all post types in our document system
$allowed = cornerstone('Resolver')->getAllowedPostTypes();
// Remove global block otherwise it will add twice
// through DependencyMapper
$key = array_search('cs_global_block', $allowed);
if($key !== false){
unset($allowed[$key]);
}
//$allowed[] = 'cs_template';
$tcoPosts = get_posts([
'posts_per_page' => -1,
'post_type' => $allowed,
'post_status' => ['any', 'tco-data'],
'fields' => 'ids',
]);
// testing
//$tcoPosts = [80];
//$tcoPosts = [103];
$export = $this->createExport();
$export->setOption('fullSite', true);
// Export doc
add_filter('cs_export_doc_strategy', function() {
return 'replace';
});
// Add each document to export
foreach ($tcoPosts as $id) {
$export->add($id, 'document');
}
$export->addMenus();
// Setup zip file
$export = $export->organize();
$zip = $export->archive();
// Bad zip generation
if (is_wp_error($zip)) {
throw new \DomainException($zip->get_error_message());
}
// Send file
// exits after this
$this->filesystem->sendFile($zip);
}
public function addLocalToMediaManager($fileName, $tmp_file, $postId = null) {
// Required for generate attachment metadata
require_once ABSPATH . 'wp-admin/includes/image.php';
// Send tmp file to upload dir for later attachment creation
$sideLoadFile = [
'name' => $fileName,
'tmp_name' => $tmp_file,
];
$results = wp_handle_sideload($sideLoadFile, [
'test_form' => false
]);
if ( !empty( $results['error'] ) ) {
throw new DomainException('Failed to sideload image: ' . $name);
}
// Insert to attachment table
$insertArgs = [
'post_title' => pathinfo($fileName, PATHINFO_FILENAME),
'post_content' => '',
'post_mime_type' => $results['type'],
'guid' => $results[ 'url' ]
];
// Create new post
if (!empty($postId)) {
$insertArgs['ID'] = $postId;
}
// Create new attachment or update
$postId = wp_insert_attachment($insertArgs, $results['file'] );
// Generate metadata
wp_generate_attachment_metadata($postId, $results['file']);
return $postId;
}
}