예제 #1
1
 static function updateAssetsUrls($content, $ajaxMode)
 {
     $serverUrl = \BearCMS\Internal\Options::$serverUrl;
     if ($ajaxMode) {
         $hasChange = false;
         $contentData = json_decode($content, true);
         if (isset($contentData['jsFiles'])) {
             $newJsFiles = [];
             foreach ($contentData['jsFiles'] as $src) {
                 if (isset($src[0]) && strpos($src, $serverUrl) === 0) {
                     $hasChange = true;
                     $scriptBundle[] = $src;
                 } else {
                     $newJsFiles[] = $src;
                 }
             }
             if (!empty($scriptBundle)) {
                 $newJsFiles[] = self::getAssetsUrl(array_unique($scriptBundle));
             }
             $contentData['jsFiles'] = $newJsFiles;
         }
         if ($hasChange) {
             return json_encode($contentData);
         }
     } else {
         $hasChange = false;
         $dom = new \IvoPetkov\HTML5DOMDocument();
         $dom->loadHTML($content);
         $scripts = $dom->querySelectorAll('script');
         $scriptBundle = [];
         $scriptsToRemove = [];
         foreach ($scripts as $script) {
             $src = (string) $script->getAttribute('src');
             if (isset($src[0]) && strpos($src, $serverUrl) === 0) {
                 $hasChange = true;
                 if ($script->getAttribute('async') === 'async') {
                     $scriptsToRemove[] = $script;
                     $scriptBundle[] = $src;
                 } else {
                     $script->setAttribute('src', self::getAssetsUrl([$src]));
                 }
             }
         }
         foreach ($scriptsToRemove as $script) {
             $script->parentNode->removeChild($script);
         }
         if (!empty($scriptBundle)) {
             $script = $dom->createElement('script');
             $script->setAttribute('async', 'async');
             $script->setAttribute('src', self::getAssetsUrl(array_unique($scriptBundle)));
             $dom->querySelector('body')->appendChild($script);
         }
         if ($hasChange) {
             return $dom->saveHTML();
         }
     }
     return $content;
 }
 /**
  * Sets the value for the property specified
  * 
  * @param string $name
  * @param string $value
  * @throws \InvalidArgumentException
  * @throws \Exception
  */
 public function __set($name, $value)
 {
     if (!is_string($value)) {
         throw new \InvalidArgumentException('The value argument must be of type string');
     }
     if ($name === 'innerHTML') {
         while ($this->hasChildNodes()) {
             $this->removeChild($this->firstChild);
         }
         $tmpDoc = new \IvoPetkov\HTML5DOMDocument();
         $tmpDoc->loadHTML('<body>' . $value . '</body>');
         foreach ($tmpDoc->getElementsByTagName('body')->item(0)->childNodes as $node) {
             $node = $this->ownerDocument->importNode($node, true);
             $this->appendChild($node);
         }
         return;
     } elseif ($name === 'outerHTML') {
         $tmpDoc = new \IvoPetkov\HTML5DOMDocument();
         $tmpDoc->loadHTML('<body>' . $value . '</body>');
         foreach ($tmpDoc->getElementsByTagName('body')->item(0)->childNodes as $node) {
             $node = $this->ownerDocument->importNode($node, true);
             $this->parentNode->insertBefore($node, $this);
         }
         $this->parentNode->removeChild($this);
         return;
     }
     throw new \Exception('Undefined property: HTML5DOMElement::$' . $name);
 }
$attributes = '';
$attributes .= ' type="' . $menuType . '"';
if (strlen($component->class) > 0) {
    $attributes .= ' class="' . htmlentities($component->class) . '"';
}
$attributes .= ' moreItemHtml="' . htmlentities('<li class="bearcms-navigation-element-item bearcms-navigation-element-item-more"><a></a><ul class="bearcms-navigation-element-item-children"></ul></li>') . '"';
$dataResponsiveAttributes = $component->getAttribute('data-responsive-attributes');
if (strlen($dataResponsiveAttributes) > 0) {
    $attributes .= ' data-responsive-attributes="' . htmlentities(str_replace('=>menuType=', '=>type=', $dataResponsiveAttributes)) . '"';
}
if ($pages !== null && $showHomeButton) {
    $pages->unshift(new \BearCMS\DataObject(['id' => '_home', 'path' => '/', 'name' => $homeButtomText, 'parentID' => '', 'status' => 'published']));
}
$itemsHtml = (string) $component->innerHTML;
if (isset($itemsHtml[0])) {
    $domDocument = new IvoPetkov\HTML5DOMDocument();
    $domDocument->loadHTML($itemsHtml);
    $ulElements = $domDocument->querySelectorAll('ul');
    foreach ($ulElements as $index => $ulElement) {
        $ulElement->setAttribute('class', trim($ulElement->getAttribute('class') . ' ' . ($index === 0 ? 'bearcms-navigation-element' : 'bearcms-navigation-element-item-children')));
    }
    $liElements = $domDocument->querySelectorAll('li');
    foreach ($liElements as $index => $liElement) {
        $liClasssName = 'bearcms-navigation-element-item';
        if ($liElement->firstChild) {
            $liPath = str_replace($app->request->base, '', $liElement->firstChild->getAttribute('href'));
            if ($liPath === $selectedPath) {
                $liClasssName .= ' bearcms-navigation-element-item-selected';
            } elseif ($liPath !== '/' && strpos($selectedPath, $liPath) === 0) {
                $liClasssName .= ' bearcms-navigation-element-item-in-path';
            }
 static function getRawDataFromComponent($component)
 {
     $type = self::$elementTypes[$component->src];
     $data = [];
     $copyString = function ($name) use($component, &$data) {
         $data[$name] = (string) $component->{$name};
     };
     $copyBoolean = function ($name) use($component, &$data) {
         $data[$name] = $component->{$name} === 'true' ? true : false;
     };
     $copyInt = function ($name) use($component, &$data) {
         $data[$name] = (int) $component->{$name};
     };
     if ($type === 'heading') {
         $copyString('text');
         $copyString('size');
     } elseif ($type === 'text') {
         $copyString('text');
     } elseif ($type === 'link') {
         $copyString('url');
         $copyString('text');
         $copyString('title');
     } elseif ($type === 'video') {
         $copyString('url');
         $copyString('filename');
     } elseif ($type === 'image') {
         $copyString('filename');
         $copyString('title');
         $copyString('onClick');
         $copyString('url');
     } elseif ($type === 'imageGallery') {
         $copyString('type');
         $copyString('columnsCount');
         if (is_numeric($data['columnsCount'])) {
             $data['columnsCount'] = (int) $data['columnsCount'];
         }
         $copyString('imageSize');
         $copyString('imageAspectRatio');
         $data['files'] = [];
         if (strlen($component->innerHTML) > 0) {
             $domDocument = new \IvoPetkov\HTML5DOMDocument();
             $domDocument->loadHTML($component->innerHTML);
             $files = $domDocument->querySelectorAll('file');
             foreach ($files as $file) {
                 $filename = $file->getAttribute('filename');
                 $data['files'][] = ['filename' => $filename];
             }
         }
     } elseif ($type === 'navigation') {
         $copyString('type');
         $copyString('pageID');
     } elseif ($type === 'html') {
         $copyString('code');
     } elseif ($type === 'blogPosts') {
         $copyString('type');
         $copyBoolean('showDate');
         $copyInt('limit');
     }
     return ['id' => $component->id, 'type' => $type, 'data' => $data];
 }
 /**
  * Converts components code (if any) into HTML code
  * 
  * @param string|\IvoPetkov\HTMLServerComponent $content The content to be processed
  * @param array $options Compiler options
  * @throws \InvalidArgumentException
  * @return string The result HTML code
  */
 public function process($content, $options = [])
 {
     if (!is_string($content) && !$content instanceof \IvoPetkov\HTMLServerComponent) {
         throw new \InvalidArgumentException('');
     }
     if (!is_array($options)) {
         throw new \InvalidArgumentException('');
     }
     if (is_string($content) && strpos($content, '<component') === false) {
         return $content;
     }
     if (isset($options['_internal_process_components']) && $options['_internal_process_components'] === false) {
         return $content;
     }
     $getComponentFileContent = function ($file, $component, $variables) {
         if (is_file($file)) {
             $__componentFile = $file;
             unset($file);
             if (!empty($variables)) {
                 extract($variables, EXTR_SKIP);
             }
             unset($variables);
             ob_start();
             include $__componentFile;
             $content = ob_get_clean();
             return $content;
         } else {
             throw new \Exception('Component file cannot be found (' . $file . ')');
         }
     };
     $getComponentResultHTML = function ($component) use(&$getComponentFileContent, $options) {
         if (isset($component->attributes['src'])) {
             // todo check alias of alias
             $srcAttributeValue = $component->attributes['src'];
             if (isset($this->aliases[$srcAttributeValue])) {
                 $sourceParts = explode(':', $this->aliases[$srcAttributeValue], 2);
             } else {
                 $sourceParts = explode(':', $srcAttributeValue, 2);
             }
             if (sizeof($sourceParts) === 2) {
                 $scheme = $sourceParts[0];
                 if (isset($options['recursive']) && $options['recursive'] === false) {
                     $componentOptions = array_merge($options, ['_internal_process_components' => false]);
                 }
                 if ($scheme === 'data') {
                     if (substr($sourceParts[1], 0, 7) === 'base64,') {
                         return $this->process(base64_decode(substr($sourceParts[1], 7)), isset($componentOptions) ? $componentOptions : $options);
                     }
                     throw new \Exception('Components data URI scheme only supports base64 (data:base64,ABCD...)!');
                 } elseif ($scheme === 'file') {
                     return $this->process($getComponentFileContent(urldecode($sourceParts[1]), $component, isset($options['variables']) && is_array($options['variables']) ? $options['variables'] : []), isset($componentOptions) ? $componentOptions : $options);
                 }
                 throw new \Exception('Components URI scheme not valid! It must be \'file:\', \'data:\' or an alias.');
             }
             throw new \Exception('Components URI scheme or alias not found at ' . (string) $component . '!');
         }
         throw new \Exception('Component src attribute is missing at ' . (string) $component . '!');
     };
     $domDocument = new \IvoPetkov\HTML5DOMDocument();
     if ($content instanceof \IvoPetkov\HTMLServerComponent) {
         $domDocument->loadHTML($getComponentResultHTML($content));
     } else {
         $domDocument->loadHTML($content);
         $componentElements = $domDocument->getElementsByTagName('component');
         $componentElementsCount = $componentElements->length;
         if ($componentElementsCount > 0) {
             for ($i = 0; $i < $componentElementsCount; $i++) {
                 $componentElement = $componentElements->item(0);
                 $component = $this->constructComponent($componentElement->getAttributes(), $componentElement->innerHTML);
                 $componentResultHTML = $getComponentResultHTML($component);
                 $isInBodyTag = false;
                 $parentNode = $componentElement->parentNode;
                 while ($parentNode !== null && isset($parentNode->tagName)) {
                     if ($parentNode->tagName === 'body') {
                         $isInBodyTag = true;
                         break;
                     }
                     $parentNode = $parentNode->parentNode;
                 }
                 if ($isInBodyTag) {
                     $insertTargetName = 'html-server-components-compiler-target-' . uniqid();
                     $componentElement->parentNode->insertBefore($domDocument->createInsertTarget($insertTargetName), $componentElement);
                     $domDocument->insertHTML($componentResultHTML, $insertTargetName);
                 } else {
                     $domDocument->insertHTML($componentResultHTML);
                 }
                 $componentElement->parentNode->removeChild($componentElement);
             }
         }
     }
     return $domDocument->saveHTML();
 }
}
$lazyLoadImages = false;
if ($component->lazyLoadImages === 'true') {
    $lazyLoadImages = true;
}
$galleryID = 'imggallery' . uniqid();
$containerAttributes = '';
if ($onClick === 'fullscreen') {
    $hasLightbox = true;
    $jsData = ['galleryID' => $galleryID, 'lightboxData' => ['images' => []], 'images' => []];
    $index = 0;
    foreach ($files as $file) {
        $filename = $file->getAttribute('filename');
        $imageContainerID = $galleryID . 'img' . $index;
        $html = $app->components->process('<div id="' . $imageContainerID . '"><component style="background-color:#000;" src="lazy-image" filename="' . $filename . '"/></div>');
        $imageDomDocument = new IvoPetkov\HTML5DOMDocument();
        $imageDomDocument->loadHTML($html);
        $imageHTMLBody = $imageDomDocument->querySelector('body');
        $imageHTML = $imageHTMLBody->innerHTML;
        $imageHTMLBody->parentNode->removeChild($imageHTMLBody);
        $jsData['lightboxData']['images'][] = ['html' => $imageHTML, 'onBeforeShow' => 'window.' . $galleryID . 'ig.onBeforeShow(' . $index . ');', 'onShow' => 'window.' . $galleryID . 'ig.onShow(' . $index . ');'];
        list($imageWidth, $imageHeight) = $app->images->getSize($filename);
        $jsData['images'][] = [$imageWidth, $imageHeight, $imageDomDocument->saveHTML()];
        $index++;
    }
}
$getColumnsStyle = function ($columnsCount, $attributeSelector = '') use($galleryID, $spacing) {
    $result = '#' . $galleryID . $attributeSelector . '>div{vertical-align:top;display:inline-block;width:calc((100% - ' . $spacing . '*' . ($columnsCount - 1) . ')/' . $columnsCount . ');margin-right:' . $spacing . ';margin-top:' . $spacing . ';}';
    $result .= '#' . $galleryID . $attributeSelector . '>div:nth-child(' . $columnsCount . 'n){margin-right:0;}';
    for ($i = 1; $i <= $columnsCount; $i++) {
        $result .= '#' . $galleryID . $attributeSelector . '>div:nth-child(' . $i . '){margin-top:0;}';
<?php

/*
 * Bear CMS addon for Bear Framework
 * https://bearcms.com/
 * Copyright (c) 2016 Amplilabs Ltd.
 * Free to use under the MIT license.
 */
use BearFramework\App;
$app = App::get();
$domDocument = new IvoPetkov\HTML5DOMDocument();
$domDocument->loadHTML($component->innerHTML);
$files = $domDocument->querySelectorAll('file');
$spacing = $component->spacing;
$content = '<div class="bearcms-image-gallery-element" style="font-size:0;">';
$attributes = '';
if (strlen($component->type) > 0) {
    $attributes .= ' type="' . $component->type . '"';
}
if (strlen($component->columnsCount) > 0) {
    $attributes .= ' columnsCount="' . $component->columnsCount . '"';
}
if (strlen($component->imageSize) > 0) {
    $attributes .= ' imageSize="' . $component->imageSize . '"';
}
if (strlen($component->imageAspectRatio) > 0) {
    $attributes .= ' imageAspectRatio="' . $component->imageAspectRatio . '"';
}
if (strlen($component->imageLoadingBackground) > 0) {
    $attributes .= ' imageLoadingBackground="' . $component->imageLoadingBackground . '"';
}
$temp = (string) $component->type;
if ($temp !== '') {
    if (array_search($temp, ['horizontal-down', 'vertical-left', 'vertical-right', 'list-vertical', 'list-horizontal']) !== false) {
        $type = $temp;
    }
}
$moreItemHtml = '<li><a>...</a><ul></ul></li>';
$temp = (string) $component->moreItemHtml;
if ($temp !== '') {
    $moreItemHtml = $temp;
}
$innerHTML = trim($component->innerHTML);
if (!isset($innerHTML[0])) {
    $innerHTML = '<ul></ul>';
}
$domDocument = new IvoPetkov\HTML5DOMDocument();
$domDocument->loadHTML($innerHTML);
$rootElement = $domDocument->querySelector('ul');
if ($rootElement === null) {
    return;
}
$elementID = 'nvgmn' . md5(uniqid());
$rootElement->setAttribute('id', $elementID);
if ($type === 'horizontal-down' || $type === 'vertical-left' || $type === 'vertical-right') {
    $rootElement->setAttribute('data-nm-type', $type);
    $rootElement->setAttribute('data-nm-more', $moreItemHtml);
}
$dataResponsiveAttributes = $component->getAttribute('data-responsive-attributes');
if (strlen($dataResponsiveAttributes) > 0) {
    $rootElement->setAttribute('data-responsive-attributes', str_replace('=>type=', '=>data-nm-type=', $dataResponsiveAttributes));
}
 static function replaceContent($data, $response)
 {
     $app = App::$instance;
     $body = $response['body'];
     $content = $app->components->process($data['content']);
     $domDocument = new \IvoPetkov\HTML5DOMDocument();
     $domDocument->loadHTML($content);
     $bodyElement = $domDocument->querySelector('body');
     $content = $bodyElement->innerHTML;
     $bodyElement->parentNode->removeChild($bodyElement);
     $allButBody = $domDocument->saveHTML();
     $startPosition = strpos($body, '{bearcms-replace-content-' . $data['id'] . '-');
     if ($startPosition === false) {
         return;
     }
     $endPosition = strpos($body, '}', $startPosition);
     $modificationsString = substr($body, $startPosition + 58, $endPosition - $startPosition - 58);
     $parts = explode('\'', $modificationsString);
     $singleQuoteSlashesCount = strlen($parts[0]);
     $doubleQuoteSlashesCount = strlen($parts[1]) - 1;
     for ($i = 0; $i < $doubleQuoteSlashesCount; $i += 2) {
         $content = substr(json_encode($content), 1, -1);
     }
     for ($i = 0; $i < $singleQuoteSlashesCount; $i += 2) {
         $content = addslashes($content);
     }
     $body = str_replace(substr($body, $startPosition, $endPosition - $startPosition + 1), $content, $body);
     //todo optimize
     $response1 = ['js' => 'html5DOMDocument.insert(' . json_encode($allButBody, true) . ');'];
     $response2 = json_decode($body, true);
     $response['body'] = json_encode(Server::mergeAjaxResponses($response1, $response2));
 }