Пример #1
0
 /**
  * Check object $field field value as $table column
  * and if database table does not have it - create.
  * $field is not set in object - error returns
  *
  * @param object $object Pointer to object to get field names data
  * @param string $table Database table name
  * @param string $field Object field name
  * @param string $type Database column name
  *
  * @return bool True if database table has field or field has been created
  */
 public function createField($object, $table, $field, $type = 'INT')
 {
     // Check if db identifier field is configured
     if (class_exists($table)) {
         if (strlen($object->{$field})) {
             // Variable to get all social table attributes
             $attributes = array();
             // Get table attributes - PHP 5.2 compatible
             eval('$attributes = ' . $table . '::$_attributes;');
             // Remove namespaces
             $table = \samson\core\AutoLoader::getOnlyClass($table);
             // Make keys lowercase
             $attributes = array_change_key_case_unicode($attributes);
             // If table does not have defined identifier field
             if (!isset($attributes[strtolower($object->{$field})])) {
                 // Add identifier field to social users table
                 $this->simple_query('ALTER TABLE  `' . $table . '` ADD  `' . $object->{$field} . '` ' . $type . ' ');
             }
             return true;
         } else {
             // Signal error
             return e('Cannot load "' . get_class($object) . '" module - no $' . $field . ' is configured');
         }
     }
 }
Пример #2
0
 /**
  * Constructor	  
  * @param string  $base_class	    Base class in relation
  * @param string  $table_name	    Name/alias of table in relation
  * @param string  $relation_class   Classname that has to be created on joining
  * @param boolean $ignore           Flag for not creating object instances for this class
  */
 public function __construct($base_class, $table_name_simple, $relation_class = null, $ignore = false)
 {
     // If table name passed without namespace consider it as activerecord namespace
     $table_name = \samson\core\AutoLoader::className($table_name_simple, 'samson\\activerecord');
     // If relation class not specified
     if (!isset($relation_class)) {
         // if there is no class exists for table name specified
         if (!class_exists($table_name, false)) {
             // PHP < 5.3 get relation aliases
             eval('$_relation_alias = ' . $base_class . '::$_relation_alias;');
             // Try to find classname in relation aliases
             if (isset($_relation_alias[$table_name_simple])) {
                 $relation_class = \samson\core\AutoLoader::className($_relation_alias[$table_name_simple], __NAMESPACE__);
             } else {
                 if (isset($_relation_alias[$table_name])) {
                     $relation_class = \samson\core\AutoLoader::className($_relation_alias[$table_name], __NAMESPACE__);
                 } else {
                     // use thi table name as class
                     $relation_class = $table_name;
                 }
             }
         } else {
             $relation_class = $table_name;
         }
         // Try to find closest parent class to dbRecord class
         $parent_class = get_parent_class($relation_class);
         if ($parent_class != \samson\core\AutoLoader::className('dbRecord', 'samson\\activerecord')) {
             $table_name = \samson\core\AutoLoader::getOnlyClass($parent_class);
         }
     }
     // Set defined class fields
     $this->base = $base_class;
     $this->relation = $relation_class;
     $this->table = \samson\core\AutoLoader::getOnlyClass($table_name);
     $this->ignore = $ignore;
     // TODO: fix this problem
     $this->table = str_replace('samson_activerecord_', '', $this->table);
 }
Пример #3
0
 /**
  * Get CMSNav by selector
  * Field to search for can be specified, by default search if performed by URL field
  *
  * @param string $selector
  * @param string $field
  * @return string|NULL
  */
 public function &navigation($selector, $field = 'Url')
 {
     $cmsnav = null;
     // If no selector passed
     if (!isset($selector)) {
         return $cmsnav;
     }
     // If id passed switch to real table column name
     if ($field == 'id') {
         $field = 'StructureID';
     }
     // Build classname with PHP < 5.3 compatibility
     $classname = \samson\core\AutoLoader::className('CMSNav', 'samson\\cms');
     // If instance of CMSNav passed - just return it
     if (is_a($selector, $classname)) {
         return $selector;
     } else {
         if (isset(dbRecord::$instances[$classname][$selector])) {
             $cmsnav =& dbRecord::$instances[$classname][$selector];
         } else {
             if (dbQuery($classname)->cond('Active', 1)->cond($field, $selector)->join('children_relations')->join('children', '\\samson\\cms\\CMSNav')->join('parents_relations')->join('parents', '\\samson\\cms\\CMSNav')->first($cmsnav)) {
                 $cmsnav->prepare();
             }
         }
     }
     return $cmsnav;
 }
Пример #4
0
 /**
  * Remove all USE statements and replace class shortcuts to full class names
  *
  * @param string $code Code to work with
  * @param array $classes Array of class names to replace
  *
  * @return bool|mixed|string
  */
 private function removeUSEStatement($code, array $classes)
 {
     // Iterate found use statements
     foreach (array_unique($classes) as $full_class) {
         // Ignore trait uses
         if (trait_exists($full_class)) {
             continue;
         }
         // Get class shortcut
         $class_name = \samson\core\AutoLoader::getOnlyClass($full_class);
         // Check class existance
         if (!class_exists($full_class) && !interface_exists($full_class)) {
             //return e('Found USE statement for undeclared class ##', E_SAMSON_FATAL_ERROR, $full_class);
             continue;
         }
         // Replace class static call
         $code = preg_replace('/([^\\\\a-z])' . $class_name . '::/i', '$1' . $full_class . '::', $code);
         // Replace class implements calls
         $code = preg_replace('/\\s+implements(.*\\W)' . $class_name . '([^\\\\])/i', ' implements $1' . $full_class . '$2 ', $code);
         // Handle instanceof operator
         $code = preg_replace('/instanceof\\s+' . $class_name . '/i', 'instanceof ' . $full_class . '', $code);
         // Replace class extends calls
         $code = preg_replace('/extends\\s+' . $class_name . '/i', 'extends ' . $full_class . '', $code);
         // Replace multiple class extends calls
         $code = preg_replace('/\\s+extends(.*\\W),?\\s' . $class_name . '([^\\\\])/i', ' extends $1' . $full_class . '$2 ', $code);
         // Replace class hint calls
         $code = preg_replace('/(\\(|\\s|\\,)\\s*' . $class_name . '\\s*(&|$)/i', '$1' . $full_class . ' $2', $code);
         // Replace class creation call
         $code = preg_replace('/new\\s+' . $class_name . '\\s*\\(/i', 'new ' . $full_class . '(', $code);
         // Replace annotations
         $code = preg_replace('/([, (])' . $class_name . '\\s\\$/i', '$1 $2' . $full_class . ' $', $code);
     }
     return $code;
 }
Пример #5
0
/**
 * Сформировать правильное имя класса с использованием namespace, если оно не указано
 * Функция нужна для обратной совместимости с именами классов без NS
 *
 * @param string $class_name Имя класса для исправления
 * @param string $ns         Пространство имен которому принадлежит класс
 *
 * @deprecated use \samson\core\AutoLoader::value() and pass full class name to it without splitting into class
 *             name and namespace
 * @return string Исправленное имя класса
 */
function ns_classname($class_name, $ns = null)
{
    return \samson\core\AutoLoader::className($class_name, $ns);
}
Пример #6
0
 /** Callback for CSS url rewriting */
 public function src_replace_callback($matches)
 {
     // Если мы нашли шаблон - переберем все найденные патерны
     if (isset($matches[2]) && strpos($matches[2], 'data:') === false) {
         // Remove relative path from resource path
         $url = str_replace('../', '/', $matches[2]);
         // Routes with this module controller do not need changes
         if (strpos($url, '/' . $this->id . '/') === false) {
             // Remove possible GET parameters from resource path
             if (($getStart = stripos($url, '?')) !== false) {
                 $url = substr($url, 0, $getStart);
             }
             // Remove possible HASH parameters from resource path
             if (($getStart = stripos($url, '#')) !== false) {
                 $url = substr($url, 0, $getStart);
             }
             //trace($this->c_module->id.'-'.get_class($this->c_module).'-'.$url.'-'.is_a( $this->c_module, ns_classname('ExternalModule','samson\core')));;
             // Always rewrite url's for external modules and for remote web applications
             if (is_a($this->c_module, \samson\core\AutoLoader::className('ExternalModule', 'samson\\core')) || __SAMSON_REMOTE_APP) {
                 // Build real path to resource
                 $realPath = $this->c_module->path() . $url;
                 // Try to find path in module root folder
                 if (!file_exists($realPath)) {
                     // Build path to "new" module public folder www
                     $realPath = $this->c_module->path() . __SAMSON_PUBLIC_PATH . $url;
                     // Try to find path in module Public folder
                     if (file_exists($realPath)) {
                         $url = 'www/' . $url;
                     } else {
                         // Signal error
                         //e('[##][##] Cannot find CSS resource[##] in path[##]',D_SAMSON_DEBUG, array($this->c_module->id, $realPath, $url, $this->cResource));
                     }
                 }
                 // Rewrite URL using router
                 $url = self::url($url, $this->c_module);
             } else {
                 if (is_a($this->c_module, \samson\core\AutoLoader::className('LocalModule', 'samson\\core'))) {
                     $url = url()->base() . $url;
                 }
             }
             return 'url("' . $url . '")';
         } else {
             return 'url("' . $matches[2] . '")';
         }
     } else {
         // Just return original value
         return $matches[0];
     }
 }
Пример #7
0
 /**
  * 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();';
     // Iterate all loaded modules
     foreach (s()->module_stack as &$module) {
         // Work only with compressible modules
         if (is_a($module, 'samson\\core\\iModuleCompressable')) {
             // $moduleCompressor = new Module(s(), $module, $this);
             //$moduleCompressor->compress();
         }
     }
     // Iterate core ns resources collection
     foreach (s()->load_module_stack as $id => &$data) {
         // Get module instance
         $module =& s()->module_stack[$id];
         // Work only with compressable modules
         if (is_a($module, ns_classname('iModuleCompressable', 'samson\\core'))) {
             /*if (in_array($id, array('local'))){
             			//trace($module);
             			//trace($data);
             			$this->compress_module( $module, $data );
             		}*/
             $this->compress_module($module, $data);
         }
     }
     // Iterate only local modules
     foreach (s()->module_stack as $id => &$module) {
         if (is_a($module, \samson\core\AutoLoader::classname('samson\\core\\CompressableLocalModule'))) {
             // Change path to module
             $module->path('');
         }
     }
     // If resourcer is loaded - copy css and js
     if (isset(s()->module_stack['resourcer'])) {
         // 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);
         // Manage javascript resource
         $javascriptManager = new resource\JavaScript($this);
         $javascriptManager->compress(__SAMSON_CWD__ . $rr->cached['js'], $this->output . basename($rr->cached['js']));
         // Manage CSS resource
         $cssManager = new resource\CSS($this, $rr);
         $cssManager->compress(__SAMSON_CWD__ . $rr->cached['css'], $this->output . basename($rr->cached['css']));
     }
     // 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 == Core::RENDER_ARRAY);
     // 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 == Core::RENDER_ARRAY) . '\');', $index_php);
     }
     $index_php = $this->removeBlankLines($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);
 }