/**
  * Compress web-application
  * @param boolean $debug Disable errors output
  * @param string $php_version PHP version to support
  */
 public function compress($debug = false, $environment = 'prod', $php_version = PHP_VERSION)
 {
     // Set compressed project environment
     $this->environment = $environment;
     elapsed('Started web-application compression[' . $this->environment . ']');
     s()->async(true);
     ini_set('memory_limit', '256M');
     // Check output path
     if (!isset($this->output[0])) {
         return $this->log('Cannot compress web-application from [##] - No output path is specified', $this->input);
     }
     // Define rendering model depending on PHP version
     $php_version = isset($php_version[0]) ? $php_version : PHP_VERSION;
     if (version_compare($php_version, '5.3.0', '<')) {
         $this->view_mode = Core::RENDER_ARRAY;
     }
     // Add url base to path
     $this->output .= url()->base();
     // Creating output project folder
     $result = \samson\core\File::mkdir($this->output);
     if ($result) {
         $this->log('Created output project folder [##]', $this->output);
     } else {
         if ($result == -1) {
             return $this->log('Compression failed! Cannot create output project folder [##]', $this->output);
         }
     }
     // Remove all trailing slashes
     $this->output = realpath($this->output) . '/';
     $this->log('[##]## Compressing web-application[##] from [##] to [##]', $environment, $debug ? '[DEBUG]' : '', $php_version, $this->input, $this->output);
     // Add generic composer auto loader require
     $this->php['__before_all']['composer'] = "\n" . 'if(file_exists("vendor/autoload.php")) require "vendor/autoload.php";';
     // Define global views collection
     $this->php[self::NS_GLOBAL][self::VIEWS] = "\n" . '$GLOBALS["__compressor_files"] = array();';
     // If resourcer is loaded - copy css and js
     // Link
     $rr =& s()->module_stack['resourcer'];
     // Iterate all css and js resources
     $ignoreFolders = array();
     foreach ($this->ignoredFolders as $folder) {
         $ignoreFolders[] = $this->output . $folder;
     }
     // Remove all old javascript and css
     \samson\core\File::clear($this->output, array('js', 'css'), $ignoreFolders);
     $moduleListArray = [];
     //$moduleListArray[Router::I_MAIN_PROJECT_TEMPLATE] = $this->system->module_stack;
     Event::fire(self::E_CREATE_MODULE_LIST, array(&$moduleListArray));
     $resource = new Resource($this->fileManager);
     foreach ($moduleListArray as $template => $moduleList) {
         $resourceUrls = [];
         Event::fire(self::E_CREATE_RESOURCE_LIST, array(&$resourceUrls, $moduleList));
         foreach ($resourceUrls as $type => $urls) {
             $file = $resource->compress($urls, $type, $this->output);
             $this->resourceUrlsList[$template][$type] = [DIRECTORY_SEPARATOR . $file];
         }
     }
     // Iterate core ns resources collection
     foreach (s()->module_stack as $id => &$module) {
         // Work only with compressable modules
         if (is_a($module, ns_classname('CompressInterface', 'samsonframework\\core')) || isset($this->composerParameters['samsonphp_package_compressable']) && ($this->composerParameters['samsonphp_package_compressable'] = 1)) {
             $this->compress_module($module, $module->resourceMap);
         }
         // Change path to local modules
         if (is_a($module, '\\samson\\core\\VirtualModule')) {
             $module->path('');
         }
     }
     /*foreach ($rr->cached['js'] as $jsCachedFile) {
                 // Manage javascript resource
                 $javascriptManager = new resource\JavaScript($this);
                 $javascriptManager->compress(__SAMSON_CWD__ . $jsCachedFile, $this->output . basename($jsCachedFile));
             }
     
             foreach ($rr->cached['css'] as $cssCachedFile) {
                 // Manage CSS resource
                 $cssManager = new resource\CSS($this, $rr);
                 $cssManager->compress(__SAMSON_CWD__ . $cssCachedFile, $this->output . basename($cssCachedFile));
             }*/
     //}
     // Copy main project composer.json
     $composerPath = __SAMSON_CWD__ . 'composer.json';
     if (file_exists($composerPath)) {
         // Read json file
         $composerJSON = (array) json_decode(file_get_contents($composerPath));
         // Remove development dependencies
         unset($composerJSON['require-dev']);
         // Remove autoload section
         unset($composerJSON['autoload']);
         // Remove install/update scripts
         unset($composerJSON['scripts']);
         // Write modified composer.json
         file_put_contents($this->output . 'composer.json', json_encode($composerJSON));
     }
     // Set errors output
     $this->php[self::NS_GLOBAL][self::VIEWS] .= "\n" . '\\samson\\core\\Error::$OUTPUT = ' . (!$debug ? 'false' : 'true') . ';';
     // Create SamsonPHP core compressor
     $core = new \samsonphp\compressor\Core(s(), $environment, $this);
     // Add global base64 serialized core string
     $this->php[self::NS_GLOBAL][self::VIEWS] .= "\n" . '$GLOBALS["__CORE_SNAPSHOT"] = \'' . $core->compress() . '\';';
     // Add all specified requires
     foreach ($this->require as $require) {
         $this->php[self::NS_GLOBAL][self::VIEWS] .= "\n" . 'require("' . $require . '");';
     }
     // Add localization data
     $locale_str = array();
     foreach (\samson\core\SamsonLocale::$locales as $locale) {
         if ($locale != '') {
             $locale_str[] = '\'' . $locale . '\'';
         }
     }
     // Add [setlocales] code
     $this->php[self::NS_GLOBAL][self::VIEWS] .= "\n" . 'setlocales( ' . implode(',', $locale_str) . ');';
     // TODO: add generic handlers to modules to provide compressing logic for each module
     // TODO: add generic constants namespace to put all constants definition there - and put only defined constrat and redeclare them
     // TODO: WTF???? Thi must be local module logic
     // If this is remote web-app - collect local resources
     if (__SAMSON_REMOTE_APP) {
         // Gather all resources
         $path = __SAMSON_CWD__;
         $ls = array();
         s()->resources($path, $ls);
         // If we have any resources
         if (isset($ls['resources'])) {
             $this->copy_path_resources($ls['resources'], __SAMSON_CWD__, '');
         }
     }
     // If default locale is defined
     if (!defined('DEFAULT_LOCALE')) {
         define('DEFAULT_LOCALE', 'ru');
     }
     // Add default system locale to them end of core definition
     $this->php['samson\\core'][self::VIEWS] = "\n" . 'define("DEFAULT_LOCALE", "' . DEFAULT_LOCALE . '");';
     // Pointer to entry script code
     $entryScriptPath = __SAMSON_CWD__ . __SAMSON_PUBLIC_PATH . 'index.php';
     $entryScript =& $this->php[self::NS_GLOBAL][$entryScriptPath];
     // Collect all event system data
     $eventCompressor = new EventCompressor();
     $eventCompressor->collect($entryScript);
     // Remove standard framework entry point from index.php	- just preserve default controller
     if (preg_match('/start\\(\\s*(\'|\\")(?<default>[^\'\\"]+)/i', $entryScript, $matches)) {
         /*
          * Temporary solution to support compressed version, because other way localization does not work,
          * as chain is broken, first time URL object is created and URL is parsed only after start, so
          * CMS::afterCompress does not knows what is current locale and does not inject it to all material
          * queries.
          */
         $this->php[self::NS_GLOBAL][self::VIEWS] .= "\n" . 'url();';
         $this->php[self::NS_GLOBAL][self::VIEWS] .= "\n" . 's()->start(\'' . $matches['default'] . '\');';
     } else {
         e('Default module definition not found - possible errors at compressed version');
     }
     // Clear default entry point
     unset($this->php[self::NS_GLOBAL][$entryScriptPath]);
     // Set global namespace as last
     $global_ns = $this->php[self::NS_GLOBAL];
     unset($this->php[self::NS_GLOBAL]);
     $this->php[self::NS_GLOBAL] = $global_ns;
     // Set view data to the end of global namespace
     $s = $this->php[self::NS_GLOBAL][self::VIEWS];
     unset($this->php[self::NS_GLOBAL][self::VIEWS]);
     $this->php[self::NS_GLOBAL][self::VIEWS] = $s;
     // Load all OOP entities
     $classes = array();
     // Соберем коллекцию загруженных интерфейсов их файлов по пространствам имен
     $this->classes_to_ns_files(get_declared_interfaces(), $classes);
     // Соберем коллекцию загруженных классов их файлов по пространствам имен
     $this->classes_to_ns_files(get_declared_classes(), $classes);
     // Fix OOP entities
     foreach ($this->php as $ns => &$files) {
         // If this namespace has been loaded
         if (isset($classes[$ns])) {
             // Fill namespace entities, make OOP entities correct order
             $files = array_merge($classes[$ns], $files);
         }
     }
     // Соберем весь PHP код в один файл
     $index_php = $this->code_array_to_str($this->php, $this->view_mode == 2);
     // Collect all event system data
     $eventCompressor->collect($index_php);
     // Transform event system in all project code
     if ($eventCompressor->transform($index_php, $index_php)) {
         //trace($eventCompressor->subscriptions, true);
     }
     // Remove url_base parsing and put current url base
     if (preg_match('/define\\(\'__SAMSON_BASE__\',\\s*([^;]+)/i', $index_php, $matches)) {
         $index_php = str_replace($matches[0], 'define(\'__SAMSON_BASE__\',\'' . __SAMSON_BASE__ . '\');', $index_php);
     }
     // Set global constant to specify supported PHP version
     if (preg_match('/define\\s*\\(\'__SAMSON_PHP_OLD[^;]+/', $index_php, $matches)) {
         $index_php = str_replace($matches[0], 'define(\'__SAMSON_PHP_OLD\',\'' . ($this->view_mode == 2) . '\');', $index_php);
     }
     $index_php = $this->removeBlankLines($index_php);
     $index_php = preg_replace('/(declare *\\( *strict_types *= *1 *\\) *;)/i', ' ', $index_php);
     // Запишем пусковой файл
     file_put_contents($this->output . 'index.php', '<?php ' . $index_php . "\n" . '?>');
     // Minify PHP code if no debug is needed
     if (!$debug) {
         file_put_contents($this->output . 'index.php', php_strip_whitespace($this->output . 'index.php'));
     }
     elapsed('Site has been successfully compressed to ' . $this->output);
 }
Exemple #2
0
 /**
  *
  * @param unknown $object
  * @param string $viewprefix
  */
 private function _setObject($object, $viewprefix = null)
 {
     // Generate viewprefix as only lowercase classname without NS if it is not specified
     $class_name = is_string($viewprefix) ? $viewprefix : '' . mb_strtolower(ns_classname(get_class($object)), 'UTF-8');
     // Save object to view data
     $this->data[$class_name] = $object;
     // Add separator
     $class_name .= '_';
     // Generate objects view array data and merge it with view data
     $this->data = array_merge($this->data, $object->toView($class_name));
 }
 /** @see \samson\core\ExternalModule::init() */
 public function prepare(array $params = null)
 {
     // TODO: Change this logic to make tab loading more simple
     // Create new gallery tab object to load it
     class_exists(ns_classname('RelatedTabLocalized', 'samson\\cms\\web\\relatedmaterial'));
 }
Exemple #4
0
 /**
  * Constructor
  * @param string $material_id CMSMaterial identifier
  */
 public function __construct($material_id = null, $parentStructure = null)
 {
     // Variable to store navigation ids to get fields by them from structurefields
     $navigationForFields = array();
     // Add structure material condition
     $scg = new dbConditionGroup('or');
     $scg->arguments[] = new dbConditionArgument(dbMySQLConnector::$prefix . 'structurematerial_Active', 1);
     $scg->arguments[] = new dbConditionArgument(dbMySQLConnector::$prefix . 'structurematerial_Active', NULL, dbRelation::ISNULL);
     // Perform CMSMaterial request with related CMSNavs
     if (dbQuery(ns_classname('CMSMaterial', 'samson\\cms'))->MaterialID($material_id)->join('structurematerial')->join('structure')->join('user')->Active(1)->cond($scg)->first($this->material)) {
         // Existing material handling
         // If material has relations with cmsnav
         $cmsnavs =& $this->material->onetomany['_structure'];
         if (isset($cmsnavs)) {
             // WYSIWYG query
             $fields_query = dbQuery('\\samson\\cms\\CMSNavField')->join('\\samson\\cms\\CMSField')->order_by('FieldID', 'ASC')->Active(1);
             // If material has related cmsnavs - gather material related cmsnavs info
             foreach ($cmsnavs as $structure) {
                 $this->navs[$structure->id] = $structure;
                 if ($structure->type != 2) {
                     $navigationForFields[] = $structure->id;
                 }
             }
             // Add cmsnavs ids to query
             $fields_query->StructureID($navigationForFields);
             // Perform DB request
             if ($fields_query->exec($fields)) {
                 foreach ($fields as $data) {
                     // Pointer to field object
                     $db_field =& $data->onetoone['_field'];
                     // Add field data to collection
                     $this->fields[] = $db_field;
                     if (isset($db_field->Type) && $db_field->Type == '8') {
                         $this->tabs[] = new MaterialFieldLocalizedTab($this, $db_field, 'WYSIWYG');
                     }
                 }
             }
         }
     } else {
         // Material empty draft creation
         $this->material = new CMSMaterial();
         $this->material->Draft = $this->material->id;
         $this->material->Name = 'Новый материал';
         $this->material->Created = date('h:m:i d.m.y');
         //			$this->material->UserID = auth()->user->id;
         $this->material->UserID = m('social')->user()->UserID;
         $this->material->Active = 1;
         $this->material->save();
         if (isset($parentStructure)) {
             /** @var \samson\cms\web\navigation\CMSNav $str */
             $str = null;
             if (dbQuery('\\samson\\cms\\web\\navigation\\CMSNav')->id($parentStructure)->first($str)) {
                 while (isset($str)) {
                     $this->navs[$str->id] = $str;
                     $str = $str->parent();
                 }
             }
         }
     }
     // Autoload base tab classes
     class_exists('samsoncms\\app\\material\\MainTab');
     class_exists('samsoncms\\app\\material\\FieldLocalizedTab');
     // Iterate declared classes to find other FormTab children to load to form
     foreach (get_declared_classes() as $class) {
         // If class if samson\cms\web\material\FormTab child
         if (is_subclass_of($class, ns_classname('FormTab', 'samsoncms\\app\\material'))) {
             // Tab supports automatic rendering flag
             eval('$ar = ' . $class . '::$AUTO_RENDER;');
             // PHP 5.2 support
             if ($ar === true) {
                 // Create and add FormTab instance to form tabs collection
                 $this->tabs[] = new $class($this);
             }
         }
     }
     // Sort tabs by their index
     usort($this->tabs, array($this, 'tabs_sorter'));
 }
 /**
  * Преобразовать массив записей из БД во внутреннее представление dbRecord
  * @param string $class_name Имя класса
  * @param array $response Массив записей полученных из БД
  * @return array Коллекцию записей БД во внутреннем формате
  * @see dbRecord
  */
 protected function &toRecords($class_name, array &$response, array $join = array(), array $virtual_fields = array())
 {
     // Сформируем правильное имя класса
     $class_name = ns_classname($class_name, 'samson\\activerecord');
     // Результирующая коллекция полученных записей из БД
     $collection = array();
     // Получим переменные для запроса
     extract($this->__get_table_data($class_name));
     // Generate table metadata for joined tables
     $joinedTableData = array();
     foreach ($join as $relationData) {
         // Generate full joined table name(including prefix)
         $joinTable = self::$prefix . $relationData->table;
         // Get real classname of the table without alias
         $tableName = $_relation_alias[$joinTable];
         // Get joined table class metadata
         $joinedTableData[$tableName] = $this->__get_table_data($tableName);
     }
     // Получим имя главного
     $main_primary = $_primary;
     // Перебем массив полученных данных от БД - создадим для них объекты
     $records_count = sizeof($response);
     // Идентификатор текущего создаваемого объекта
     $main_id = isset($response[0]) ? $response[0][$main_primary] : 0;
     // Указатель на текущий обрабатываемый объект
     $main_obj = null;
     // Переберем полученные записи из БД
     for ($i = 0; $i < $records_count; $i++) {
         // Строка данных полученная из БД
         $db_row =& $response[$i];
         // Get object instance
         $collection[$main_id] =& $this->createObject($class_name, $main_id, $_attributes, $db_row, $virtual_fields);
         // Pointer to main object
         $main_obj =& $collection[$main_id];
         // Выполним внутренний перебор строк из БД начиная с текущей строки
         // Это позволит нам розабрать объекты полученные со связью один ко многим
         // А если это связь 1-1 то цикл выполниться только один раз
         for ($j = $i; $j < $records_count; $j++) {
             // Строка данных полученная из БД
             $db_inner_row =& $response[$j];
             // Получим идентфиикатор главного объекта в текущей строче БД
             $obj_id = $db_inner_row[$main_primary];
             // Если в строке из БД новый идентификатор
             if ($obj_id != $main_id) {
                 // Установим новый текущий идентификатор материала
                 $main_id = $obj_id;
                 // Установим индекс главного цикла на строку с новым главным элементом
                 // учтем что главный цикл сам увеличит на единицу индекс
                 $i = $j - 1;
                 //trace(' - Найден новый объект на строке №'.$j.'-'.$db_inner_row[$main_primary]);
                 // Прервем внутренний цикл
                 break;
             }
             //else trace(' + Заполняем данные из строки №'.$j);
             // Переберем все присоединенные таблицы в запросе
             foreach ($join as $relation_data) {
                 /**@var \samson\activerecord\RelationData $relation_data */
                 // If this table is not ignored
                 if (!$relation_data->ignore) {
                     // TODO: Prepare all data in RelationObject to speed up this method
                     $join_name = $relation_data->relation;
                     $join_table = self::$prefix . $relation_data->table;
                     //trace('Filling related table:'.$join_name.'/'.$join_table);
                     // Get real classname of the table without alias
                     $_relation_name = $_relation_alias[$join_table];
                     $join_class = str_replace(self::$prefix, '', $relation_data->table);
                     // Get joined table metadata from previously prepared object
                     $r_data = $joinedTableData[$_relation_name];
                     // Try to get identifier
                     if (isset($_relations[$join_table][$r_data['_primary']])) {
                         $r_obj_id_field = $_relations[$join_table][$r_data['_primary']];
                     } else {
                         e('Cannot find related table(##) primary field(##) description', E_SAMSON_ACTIVERECORD_ERROR, array($join_table, $r_data['_primary']));
                     }
                     // Если задано имя ключевого поля связанного объекта - создадим его
                     if (isset($db_inner_row[$r_obj_id_field])) {
                         // Получим ключевое поле связанного объекта
                         $r_obj_id = $db_inner_row[$r_obj_id_field];
                         // Get joined object instance
                         $r_obj =& $this->createObject($join_name, $r_obj_id, $_relations[$join_table], $db_inner_row);
                         // Call handler for object filling
                         $r_obj->filled();
                         // TODO: Это старый подход - сохранять не зависимо от алиаса под реальным именем таблицы
                         // Если связанный объект привязан как один-к-одному - просто довами ссылку на него
                         if ($_relation_type[$join_table] == 0) {
                             $main_obj->onetoone['_' . $join_table] = $r_obj;
                             $main_obj->onetoone['_' . $join_class] = $r_obj;
                         } else {
                             $main_obj->onetomany['_' . $join_table][$r_obj_id] = $r_obj;
                             $main_obj->onetomany['_' . $join_class][$r_obj_id] = $r_obj;
                         }
                     }
                 }
             }
         }
         // Call handler for object filling
         $main_obj->filled();
         // Если внутренний цикл дошел до конца остановим главный цикл
         if ($j == $records_count) {
             break;
         }
     }
     // Вернем то что у нас вышло
     return $collection;
 }
Exemple #6
0
 /**
  * Get CMSMaterial by selector
  * Field to search for can be specified, by default search if performed by URL field
  * Function supports finding material by own fields and by any additional fields
  *
  * @param string $selector Value of CMSMaterial to search
  * @param string $field Field name for searching
  * @return CMSMaterial Instance of CMSMaterial on successfull search
  */
 public function &material($selector, $field = 'Url')
 {
     $db_cmsmat = null;
     // If id passed switch to real table column name
     if ($field == 'id') {
         $field = 'MaterialID';
     }
     // Build classname with PHP < 5.3 compatibility
     $classname = ns_classname('cmsmaterial', 'samson\\cms');
     // If instance of CMSMaterial passed - just return it
     if ($selector instanceof $classname) {
         return $selector;
     } else {
         if (isset(dbRecord::$instances[$classname][$selector])) {
             $db_cmsmat =& dbRecord::$instances[$classname][$selector];
         } else {
             // Get material	by field
             $db_cmsmat = CMSMaterial::get(array($field, $selector), NULL, 0, 1);
             // If we have found material - get the first one
             if (is_array($db_cmsmat) && sizeof($db_cmsmat)) {
                 $db_cmsmat = array_shift($db_cmsmat);
             } else {
                 $db_cmsmat = null;
             }
         }
     }
     return $db_cmsmat;
 }