first commit
This commit is contained in:
497
wp-content/plugins/brizy/editor/zip/archiver.php
Normal file
497
wp-content/plugins/brizy/editor/zip/archiver.php
Normal file
@@ -0,0 +1,497 @@
|
||||
<?php
|
||||
|
||||
class Brizy_Editor_Zip_Archiver implements Brizy_Editor_Zip_ArchiverInterface {
|
||||
use Brizy_Editor_Asset_AttachmentAware;
|
||||
|
||||
const ARCHIVE_TYPE_LAYOUT = 'layout';
|
||||
const ARCHIVE_TYPE_BLOCK = 'block';
|
||||
const ARCHIVE_TYPE_POPUP = 'popup';
|
||||
|
||||
/**
|
||||
* @var Brizy_Editor_Project
|
||||
*/
|
||||
protected $project;
|
||||
/**
|
||||
* @var Brizy_Admin_Fonts_Manager
|
||||
*/
|
||||
protected $fontManager;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $editorVersion;
|
||||
|
||||
public function __construct(
|
||||
Brizy_Editor_Project $project,
|
||||
Brizy_Admin_Fonts_Manager $fontManager,
|
||||
$editorVersion
|
||||
) {
|
||||
$this->project = $project;
|
||||
$this->fontManager = $fontManager;
|
||||
$this->editorVersion = $editorVersion;
|
||||
|
||||
if ( ! class_exists( 'ZipArchive' ) ) {
|
||||
throw new InvalidArgumentException( __( 'Please install/enable php zip extension. Contact your hosting company for more info and help.' ) );
|
||||
}
|
||||
}
|
||||
|
||||
public function getScreenshotType( $archiveType ) {
|
||||
switch ( $archiveType ) {
|
||||
case Brizy_Editor_Layout::class:
|
||||
return Brizy_Editor_Screenshot_Manager::BLOCK_TYPE_LAYOUT;
|
||||
case Brizy_Editor_Block::class:
|
||||
return Brizy_Editor_Screenshot_Manager::BLOCK_TYPE_SAVED;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Brizy_Editor_Zip_ArchiveItem[] $archiveItems
|
||||
* @param null $outZipPath
|
||||
*
|
||||
* @return mixed|string|null
|
||||
* @throws Exception
|
||||
*/
|
||||
public function createZip( $archiveItems, $fileName ) {
|
||||
|
||||
wp_raise_memory_limit( 'image' );
|
||||
|
||||
// create archive folder
|
||||
$outZipPath = $this->prepareArchiveFilepath( $fileName );
|
||||
|
||||
$z = new ZipArchive();
|
||||
$z->open( $outZipPath, ZipArchive::CREATE );
|
||||
|
||||
foreach ( $archiveItems as $item ) {
|
||||
$this->addEntityToZip( $z, $item );
|
||||
}
|
||||
|
||||
if ( ! $z->close() ) {
|
||||
throw new Exception( __( 'Failed to create archive.' ) );
|
||||
}
|
||||
unset( $z );
|
||||
|
||||
return $outZipPath;
|
||||
}
|
||||
|
||||
public function addEntityToZip( ZipArchive $z, Brizy_Editor_Zip_ArchiveItem $item ) {
|
||||
// get block data
|
||||
$block = $item->getPost();
|
||||
$data = array(
|
||||
'class' => get_class( $block ),
|
||||
'meta' => $block->getMeta(),
|
||||
'media' => $block->getMedia(),
|
||||
'data' => $block->get_editor_data(),
|
||||
'editorVersion' => $block->get_editor_version(),
|
||||
'files' => [
|
||||
'images' => [],
|
||||
'uploads' => [],
|
||||
'screenshots' => [],
|
||||
'fonts' => [],
|
||||
],
|
||||
'hasPro' => $item->isPro()
|
||||
);
|
||||
|
||||
$z->addEmptyDir( $block->getUid() );
|
||||
|
||||
$media = json_decode( $block->getMedia() );
|
||||
$meta = json_decode( $block->getMeta() );
|
||||
$manager = new Brizy_Editor_Screenshot_Manager( new Brizy_Editor_UrlBuilder( $this->project, $block ) );
|
||||
|
||||
// create block data json file
|
||||
$data = $this->addImages( $z, $media, $data, $block->getUid() );
|
||||
$data = $this->addUploads( $z, $media, $data, $block->getUid() );
|
||||
$data = $this->addFonts( $z, $media, $data, $block->getUid() );
|
||||
$data = $this->addScreenshot( $z, $meta, $manager, $data, $block->getUid() );
|
||||
|
||||
$z->addFromString( $block->getUid() . "/data.json", json_encode( $data ) );
|
||||
}
|
||||
|
||||
public function createFromZip( $zipPath ) {
|
||||
|
||||
wp_raise_memory_limit( 'image' );
|
||||
|
||||
global $wpdb;
|
||||
if ( ! file_exists( $zipPath ) ) {
|
||||
Brizy_Logger::instance()->error( 'Unable to find the archive path.', [ 'path' => $zipPath ] );
|
||||
throw new Exception( __( 'Unable to find the archive.' ) );
|
||||
}
|
||||
$z = new ZipArchive();
|
||||
$z->open( $zipPath );
|
||||
$instances = [];
|
||||
$failed = [];
|
||||
// As long as statIndex() does not return false keep iterating
|
||||
|
||||
try {
|
||||
$wpdb->query( "START TRANSACTION" );
|
||||
//find root folders
|
||||
$folders = [];
|
||||
for ( $i = 0; $i < $z->numFiles; $i ++ ) {
|
||||
$name = $z->getNameIndex( $i );
|
||||
$parts = explode( '/', $name );
|
||||
if ( count( $parts ) ) {
|
||||
$folders[] = $parts[0];
|
||||
}
|
||||
}
|
||||
$folders = array_unique( $folders );
|
||||
foreach ( $folders as $folder ) {
|
||||
try {
|
||||
$instances[] = $this->createSingleFromZipPath( $z, $folder );
|
||||
} catch ( Exception $e ) {
|
||||
$failed[] = [ 'uid' => $folder, 'message' => $e->getMessage() ];
|
||||
}
|
||||
}
|
||||
|
||||
$wpdb->query( "COMMIT" );
|
||||
} catch ( Exception $e ) {
|
||||
$wpdb->query( "ROLLBACK" );
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$z->close();
|
||||
|
||||
return [ $instances, $failed ];
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
private function createSingleFromZipPath( ZipArchive $z, $dir ) {
|
||||
|
||||
$data = json_decode( $z->getFromName( $dir . '/data.json' ) );
|
||||
$hasPro = (bool) $data->hasPro;
|
||||
|
||||
if ( $hasPro ) {
|
||||
|
||||
$throw = false;
|
||||
|
||||
if ( ! class_exists( 'BrizyPro_Admin_License' ) ) {
|
||||
$throw = true;
|
||||
} else {
|
||||
if ( method_exists( BrizyPro_Admin_License::_init(), 'isValidLicense' ) ) {
|
||||
if ( ! BrizyPro_Admin_License::_init()->isValidLicense() ) {
|
||||
$throw = true;
|
||||
}
|
||||
} else {
|
||||
if ( ! BrizyPro_Admin_License::_init()->getCurrentLicense() ) {
|
||||
$throw = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $throw ) {
|
||||
throw new Exception( 'Attempt to import a PRO block in a non PRO environment.' );
|
||||
}
|
||||
}
|
||||
|
||||
$entityClass = $data->class;
|
||||
|
||||
if ( ! class_exists( $entityClass ) ) {
|
||||
Brizy_Logger::instance()->error( "Unsupported object found in zip file", [ 'class' => $entityClass ] );
|
||||
throw new Exception( __( "Unsupported object found in zip file" ) );
|
||||
}
|
||||
|
||||
if ( ! $this->isVersionSupported( $data->editorVersion ) ) {
|
||||
Brizy_Logger::instance()->error( "Unsupported zip file version", [ 'version' => $data->editorVersion ] );
|
||||
throw new Exception( __( "Unsupported zip file version" ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @var Brizy_Editor_Post $block ;
|
||||
*/
|
||||
$block = $this->getManager( $entityClass )->createEntity( md5( random_bytes( 10 ) ), 'publish' );
|
||||
$block->set_needs_compile( true );
|
||||
$block->set_editor_data( $data->data );
|
||||
$block->setMeta( $data->meta );
|
||||
$block->setMedia( $data->media );
|
||||
$block->set_editor_version( $data->editorVersion );
|
||||
$block->setDataVersion( 1 );
|
||||
$block->save();
|
||||
|
||||
// store images
|
||||
$this->allowUploadsInCallback( function () use ( $data, $z, $block ) {
|
||||
$this->storeImages( $data, $z, $block );
|
||||
$this->storeUploads( $data, $z, $block );
|
||||
} );
|
||||
|
||||
$this->storeScreenshot( $data, $z, $block );
|
||||
$this->storeFonts( $data, $z, $block );
|
||||
|
||||
return $block;
|
||||
}
|
||||
|
||||
public function getEditorVersion() {
|
||||
return $this->editorVersion;
|
||||
}
|
||||
|
||||
public function isVersionSupported( $version ) {
|
||||
return version_compare( $this->getEditorVersion(), $version, '>=' );
|
||||
}
|
||||
|
||||
protected function prepareArchiveFilepath( $fileName ) {
|
||||
return sys_get_temp_dir() . DIRECTORY_SEPARATOR . $fileName;
|
||||
}
|
||||
|
||||
protected function storeImages( $data, ZipArchive $z, Brizy_Editor_Post $block ) {
|
||||
|
||||
$urlBuilder = new Brizy_Editor_UrlBuilder( $this->project, $block->getWpPostId() );
|
||||
foreach ( $data->files->images as $uid => $path ) {
|
||||
|
||||
if ( $this->getAttachmentByMediaName( $uid ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$basename = basename( $path );
|
||||
$original_asset_path = $urlBuilder->page_upload_path( "/assets/images/" . $basename );
|
||||
$original_asset_path_relative = $urlBuilder->page_upload_relative_path( "/assets/images/" . $basename );
|
||||
wp_mkdir_p( dirname( $original_asset_path ) );
|
||||
file_put_contents( $original_asset_path, $z->getFromName( $path ) );
|
||||
|
||||
Brizy_Editor_Asset_StaticFileTrait::createMediaAttachment( $original_asset_path,
|
||||
$original_asset_path_relative,
|
||||
$block->getWpPostId(),
|
||||
$uid );
|
||||
}
|
||||
}
|
||||
|
||||
protected function storeScreenshot( $data, ZipArchive $z, Brizy_Editor_Post $block ) {
|
||||
|
||||
$manager = new Brizy_Editor_Screenshot_Manager( new Brizy_Editor_UrlBuilder( $block ) );
|
||||
|
||||
$screens = (array) $data->files->screenshots;
|
||||
|
||||
foreach ( $screens as $uid => $filePath ) {
|
||||
$manager->saveScreenshot( $uid, $this->getScreenshotType( $data->class ), $z->getFromName( $filePath ), $block->getWpPostId() );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected function storeFonts( $data, ZipArchive $z, Brizy_Editor_Post $block ) {
|
||||
foreach ( $data->files->fonts as $fontUid => $font ) {
|
||||
$family = $font->family;
|
||||
$weights = $font->weights;
|
||||
|
||||
$newWeights = array();
|
||||
|
||||
foreach ( (array) $weights as $weight => $weightType ) {
|
||||
foreach ( (array) $weightType as $type => $filePath ) {
|
||||
$newWeights[ $weight ][ $type ] = $this->downloadFileToTemporaryFile( basename( $filePath ),
|
||||
$z->getFromName( $filePath ) );
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$this->fontManager->createFont( $fontUid, $family, $newWeights, 'uploaded' );
|
||||
} catch ( Brizy_Admin_Fonts_Exception_DuplicateFont $e ) {
|
||||
continue;
|
||||
} catch ( Exception $e ) {
|
||||
Brizy_Logger::instance()->error( $e );
|
||||
//throw new Exception( __( 'Failed to create font [' . $fontUid . '] from archive.' ) );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function storeUploads( $data, ZipArchive $z, Brizy_Editor_Post $block ) {
|
||||
|
||||
$urlBuilder = new Brizy_Editor_UrlBuilder( $this->project, $block->getWpPostId() );
|
||||
foreach ( $data->files->uploads as $uidKey => $path ) {
|
||||
list( $uid, $uploadName ) = explode( '|||', $uidKey );
|
||||
if ( $this->getAttachmentByMediaName( $uid ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$original_asset_path = $urlBuilder->brizy_upload_path( "/custom_files/" . $uploadName );
|
||||
$original_asset_path_relative = $urlBuilder->brizy_upload_relative_path( "/custom_files/" . $uploadName );
|
||||
wp_mkdir_p( dirname( $original_asset_path ) );
|
||||
file_put_contents( $original_asset_path, $z->getFromName( $path ) );
|
||||
|
||||
Brizy_Editor_Asset_StaticFileTrait::createMediaAttachment( $original_asset_path,
|
||||
$original_asset_path_relative,
|
||||
$block->getWpPostId(),
|
||||
$uid );
|
||||
}
|
||||
}
|
||||
|
||||
protected function downloadFileToTemporaryFile( $basename, $content ) {
|
||||
$filePath = tempnam( sys_get_temp_dir(), $basename );
|
||||
$result = file_put_contents( $filePath, $content );
|
||||
|
||||
if ( $result === false ) {
|
||||
Brizy_Logger::instance()->error( 'Filed to write font content', [ 'filePath' => $filePath ] );
|
||||
throw new Exception( __( 'Filed to write font content' ) );
|
||||
}
|
||||
|
||||
return array(
|
||||
'name' => $basename,
|
||||
'type' => Brizy_Public_AssetProxy::get_mime( $filePath ),
|
||||
'tmp_name' => $filePath,
|
||||
'error' => 0,
|
||||
'size' => filesize( $filePath ),
|
||||
);
|
||||
}
|
||||
|
||||
protected function getManager( $class ) {
|
||||
static $managers = [];
|
||||
|
||||
if ( isset( $managers[ Brizy_Editor_Block::class ] ) ) {
|
||||
return $managers[ Brizy_Editor_Block::class ];
|
||||
}
|
||||
|
||||
switch ( $class ) {
|
||||
case Brizy_Editor_Block::class:
|
||||
return $managers[ Brizy_Editor_Block::class ] = new Brizy_Admin_Blocks_Manager( Brizy_Admin_Blocks_Main::CP_SAVED );
|
||||
case Brizy_Editor_Layout::class:
|
||||
return $managers[ Brizy_Editor_Layout::class ] = new Brizy_Admin_Layouts_Manager();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ZipArchive $z
|
||||
* @param $block
|
||||
* @param $filesImagesPath
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function addImages( ZipArchive $z, $media, array $data, $dir ) {
|
||||
$z->addEmptyDir( $filesImagesPath = $dir . '/files/images' );
|
||||
|
||||
foreach ( $media->images as $mediaUid ) {
|
||||
$mediaId = (int) $this->getAttachmentByMediaName( $mediaUid );
|
||||
if ( ! $mediaId ) {
|
||||
continue;
|
||||
}
|
||||
$imagePath = get_attached_file( $mediaId );
|
||||
$imageName = basename( $imagePath );
|
||||
if ( file_exists( $imagePath ) ) {
|
||||
$path = $filesImagesPath . "/" . $imageName;
|
||||
$z->addFile( $imagePath, $path );
|
||||
$data['files']['images'][ $mediaUid ] = $path;
|
||||
} else {
|
||||
Brizy_Logger::instance()->error( 'Archive object failed. The file ' . $imagePath . ' does not exist', [] );
|
||||
//throw new Exception( __( 'Archive object failed. The file ' . $imagePath . ' does not exist' ) );
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ZipArchive $z
|
||||
* @param $media
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function addUploads( ZipArchive $z, $media, array $data, $dir ) {
|
||||
|
||||
$z->addEmptyDir( $filesUploadsPath = $dir . '/files/uploads' );
|
||||
foreach ( $media->uploads as $mediaUpload ) {
|
||||
list( $uploadUid, $uploadName ) = explode( '|||', $mediaUpload );
|
||||
$mediaId = (int) $this->getAttachmentByMediaName( $uploadUid );
|
||||
$filePath = get_attached_file( $mediaId );
|
||||
$fileName = basename( $filePath );
|
||||
if ( file_exists( $filePath ) ) {
|
||||
$path = $filesUploadsPath . "/" . $fileName;
|
||||
$z->addFile( $filePath, $path );
|
||||
$data['files']['uploads'][ $mediaUpload ] = $path;
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $media
|
||||
* @param ZipArchive $z
|
||||
* @param $filesFontsPath
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function addFonts( ZipArchive $z, $media, array $data, $dir ) {
|
||||
$z->addEmptyDir( $filesFontsPath = $dir . '/files/fonts' );
|
||||
foreach ( $media->fonts as $fontUid ) {
|
||||
$fontData = $this->fontManager->getFontForExport( $fontUid );
|
||||
if ( ! $fontData ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// prepare fontData data
|
||||
foreach ( $fontData['weights'] as $weigth => $files ) {
|
||||
foreach ( $files as $type => $file ) {
|
||||
$fontName = basename( $file );
|
||||
|
||||
if ( file_exists( $file ) ) {
|
||||
$path = $filesFontsPath . "/" . $fontName;
|
||||
$z->addFile( $file, $path );
|
||||
$fontData['weights'][ $weigth ][ $type ] = $path;
|
||||
$data['files']['fonts'][ $fontUid ] = $fontData;
|
||||
} else {
|
||||
Brizy_Logger::instance()->error( 'Archive object failed. The file ' . $file . ' does not exist', [] );
|
||||
//throw new Exception( __('Archive object failed. The file ' . $file . ' does not exist') );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ZipArchive $z
|
||||
* @param $meta
|
||||
* @param $block
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function addScreenshot( ZipArchive $z, $meta, $manager, array $data, $dir ) {
|
||||
$screenUid = $meta->_thumbnailSrc;
|
||||
if ( $screenUid ) {
|
||||
|
||||
$screenPath = $manager->getScreenshot( $screenUid );
|
||||
if ( ! file_exists( $screenPath ) ) {
|
||||
Brizy_Logger::instance()->error( 'Archive object failed. The file ' . $screenPath . ' does not exist', [] );
|
||||
|
||||
//throw new Exception( __('Archive object failed. The file ' . $screenPath . ' does not exist') );
|
||||
return;
|
||||
}
|
||||
$zipScreenPath = $dir . "/files/screenshots/" . basename( $screenPath );
|
||||
$z->addFile( $screenPath, $zipScreenPath );
|
||||
$data['files']['screenshots'][ $screenUid ] = $zipScreenPath;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function allowUploadsInCallback( $callback ) {
|
||||
// enable svg upload
|
||||
$svnUpload = new Brizy_Admin_Svg_Main();
|
||||
$jsonUpload = new Brizy_Admin_Json_Main();
|
||||
$svnUploadEnabled = Brizy_Editor_Storage_Common::instance()->get( 'svg-upload', false );
|
||||
$jsonUploadEnabled = Brizy_Editor_Storage_Common::instance()->get( 'json-upload', false );
|
||||
|
||||
if ( ! $svnUploadEnabled ) {
|
||||
$svnUpload->enableSvgUpload();
|
||||
}
|
||||
if ( ! $jsonUploadEnabled ) {
|
||||
$jsonUpload->enableJsonUpload();
|
||||
}
|
||||
|
||||
$callback();
|
||||
|
||||
// disabled it if was disabled before
|
||||
if ( ! $svnUploadEnabled ) {
|
||||
$svnUpload->disableSvgUpload();
|
||||
}
|
||||
if ( ! $jsonUploadEnabled ) {
|
||||
$jsonUpload->disableJsonUpload();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user