From e9bfba959b6d655ed2eba71e4f2a618237d68698 Mon Sep 17 00:00:00 2001 From: xue <> Date: Thu, 16 Feb 2006 22:48:18 +0000 Subject: Modified asset manipulation APIs. --- .gitattributes | 1 - buildscripts/phpbuilder/files.txt | 2 +- framework/TApplication.php | 29 ++ framework/TComponent.php | 25 ++ framework/Web/Javascripts/TJSON.php | 160 ++++++----- framework/Web/Services/TPageService.php | 42 +-- framework/Web/UI/TAssetManager.php | 239 ----------------- framework/Web/UI/TClientScriptManager.php | 306 +++++++++++++++------- framework/Web/UI/TControl.php | 15 -- framework/Web/UI/TTemplateManager.php | 9 +- framework/Web/UI/WebControls/TColorPicker.php | 4 +- framework/Web/UI/WebControls/TDatePicker.php | 4 +- framework/Web/UI/WebControls/TRatingList.php | 12 +- framework/Web/UI/WebControls/TTextHighlighter.php | 2 +- 14 files changed, 365 insertions(+), 485 deletions(-) delete mode 100644 framework/Web/UI/TAssetManager.php diff --git a/.gitattributes b/.gitattributes index ccea88bc..2799bff9 100644 --- a/.gitattributes +++ b/.gitattributes @@ -663,7 +663,6 @@ framework/Web/THttpRequest.php -text framework/Web/THttpResponse.php -text framework/Web/THttpSession.php -text framework/Web/THttpUtility.php -text -framework/Web/UI/TAssetManager.php -text framework/Web/UI/TClientScriptManager.php -text framework/Web/UI/TControl.php -text framework/Web/UI/TControlAdapter.php -text diff --git a/buildscripts/phpbuilder/files.txt b/buildscripts/phpbuilder/files.txt index 0bb29bfb..c9a9d14d 100644 --- a/buildscripts/phpbuilder/files.txt +++ b/buildscripts/phpbuilder/files.txt @@ -21,13 +21,13 @@ Exceptions/TErrorHandler.php Web/THttpRequest.php Web/THttpResponse.php Web/THttpSession.php +Web/TAssetManager.php Security/TAuthorizationRule.php Security/TSecurityManager.php Web/Services/TPageService.php Web/UI/THtmlWriter.php Web/UI/TTemplateManager.php Web/UI/TThemeManager.php -Web/UI/TAssetManager.php Web/UI/TControlAdapter.php Web/UI/TControl.php Web/UI/TTemplateControl.php diff --git a/framework/TApplication.php b/framework/TApplication.php index 8c4f65f0..b61fa30d 100644 --- a/framework/TApplication.php +++ b/framework/TApplication.php @@ -38,6 +38,10 @@ require_once(PRADO_DIR.'/Security/TSecurityManager.php'); * Includes TPageService class (default service) */ require_once(PRADO_DIR.'/Web/Services/TPageService.php'); +/** + * Includes TAssetManager class + */ +require_once(PRADO_DIR.'/Web/TAssetManager.php'); /** @@ -252,6 +256,10 @@ class TApplication extends TComponent * @var TSecurityManager security manager module */ private $_security=null; + /** + * @var TAssetManager asset manager module + */ + private $_assetManager=null; /** * @var TAuthorizationRuleCollection collection of authorization rules */ @@ -677,6 +685,27 @@ class TApplication extends TComponent $this->_security=$sm; } + /** + * @return TAssetManager asset manager + */ + public function getAssetManager() + { + if(!$this->_assetManager) + { + $this->_assetManager=new TAssetManager; + $this->_assetManager->init(null); + } + return $this->_assetManager; + } + + /** + * @param TAssetManager asset manager + */ + public function setAssetManager(TAssetManager $value) + { + $this->_assetManager=$value; + } + /** * @return IStatePersister application state persister */ diff --git a/framework/TComponent.php b/framework/TComponent.php index 6641fd1a..8d6be46e 100644 --- a/framework/TComponent.php +++ b/framework/TComponent.php @@ -474,6 +474,31 @@ class TComponent { return Prado::getApplication()->getUser(); } + + /** + * Publishes a private asset and gets its URL. + * This method will publish a private asset (file or directory) + * and gets the URL to the asset. Note, if the asset refers to + * a directory, all contents under that directory will be published. + * @param string path of the asset that is relative to the directory containing the control class file. + * @return string URL to the asset path. + */ + public function publishAsset($assetPath) + { + $class=new ReflectionClass(get_class($this)); + $fullPath=dirname($class->getFileName()).'/'.$assetPath; + return $this->publishFilePath($fullPath); + } + + /** + * Publishes a file or directory and returns its URL. + * @param string absolute path of the file or directory to be published + * @return string URL to the published file or directory + */ + public function publishFilePath($fullPath) + { + return $this->getApplication()->getAssetManager()->publishFilePath($fullPath); + } } /** diff --git a/framework/Web/Javascripts/TJSON.php b/framework/Web/Javascripts/TJSON.php index 76a19d27..e653264b 100644 --- a/framework/Web/Javascripts/TJSON.php +++ b/framework/Web/Javascripts/TJSON.php @@ -1,6 +1,4 @@ * @author Matt Knapp * @author Brett Stimmerman @@ -60,7 +58,7 @@ /** * Converts to and from JSON format. * -* @package System.Web.Services.AJAX +* @package System.Web.Javascripts * @author Michal Migurski * @author Matt Knapp * @author Brett Stimmerman @@ -76,9 +74,9 @@ class TJSON /** * Marker constant for JSON::decode(), used to flag stack state - */ + */ const JSON_IN_STR = 2; - + /** * Marker constant for JSON::decode(), used to flag stack state */ @@ -91,17 +89,17 @@ class TJSON /** * Marker constant for JSON::decode(), used to flag stack state - */ + */ const JSON_IN_CMT = 16; /** * Behavior switch for JSON::decode() */ const JSON_LOOSE_TYPE = 10; - + /** * Behavior switch for JSON::decode() - */ + */ const JSON_STRICT_TYPE = 11; /** @@ -137,17 +135,17 @@ class TJSON switch (gettype($var)) { case 'boolean': return $var ? 'true' : 'false'; - + case 'NULL': return 'null'; - + case 'integer': return (int) $var; - + case 'double': case 'float': return (float) $var; - + case 'string': // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT $ascii = ''; @@ -158,9 +156,9 @@ class TJSON * escaping with a slash or encoding to UTF-8 where necessary */ for ($c = 0; $c < $strlen_var; ++$c) { - + $ord_var_c = ord($var{$c}); - + switch (true) { case $ord_var_c == 0x08: $ascii .= '\b'; @@ -184,12 +182,12 @@ class TJSON // double quote, slash, slosh $ascii .= '\\'.$var{$c}; break; - + case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): // characters U-00000000 - U-0000007F (same as ASCII) $ascii .= $var{$c}; break; - + case (($ord_var_c & 0xE0) == 0xC0): // characters U-00000080 - U-000007FF, mask 110XXXXX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 @@ -198,7 +196,7 @@ class TJSON $utf16 = $this->utf8_to_utf16be($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); break; - + case (($ord_var_c & 0xF0) == 0xE0): // characters U-00000800 - U-0000FFFF, mask 1110XXXX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 @@ -209,7 +207,7 @@ class TJSON $utf16 = $this->utf8_to_utf16be($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); break; - + case (($ord_var_c & 0xF8) == 0xF0): // characters U-00010000 - U-001FFFFF, mask 11110XXX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 @@ -221,7 +219,7 @@ class TJSON $utf16 = $this->utf8_to_utf16be($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); break; - + case (($ord_var_c & 0xFC) == 0xF8): // characters U-00200000 - U-03FFFFFF, mask 111110XX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 @@ -234,7 +232,7 @@ class TJSON $utf16 = $this->utf8_to_utf16be($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); break; - + case (($ord_var_c & 0xFE) == 0xFC): // characters U-04000000 - U-7FFFFFFF, mask 1111110X // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 @@ -250,9 +248,9 @@ class TJSON break; } } - + return '"'.$ascii.'"'; - + case 'array': /* * As per JSON spec if any array key is not an integer @@ -271,8 +269,8 @@ class TJSON * parameter is only accessible using ECMAScript's * bracket notation. */ - - // treat as a JSON object + + // treat as a JSON object if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { return '{' . join(',', array_map(array($this, 'name_value'), @@ -283,7 +281,7 @@ class TJSON // treat it like a regular array return '[' . join(',', array_map(array($this, 'encode'), $var)) . ']'; - + case 'object': $vars = get_object_vars($var); return '{' . @@ -296,7 +294,7 @@ class TJSON return ''; } } - + /** * encodes an arbitrary variable into JSON format, alias for encode() * @see JSON::encode() @@ -313,7 +311,7 @@ class TJSON { return $this->encode($var); } - + /** function name_value * array-walking function for use in generating JSON-formatted name-value pairs * @@ -326,7 +324,7 @@ class TJSON protected function name_value($name, $value) { return $this->encode(strval($name)) . ':' . $this->encode($value); - } + } /** * reduce a string by removing leading and trailing comments and whitespace @@ -339,18 +337,18 @@ class TJSON protected function reduce_string($str) { $str = preg_replace(array( - + // eliminate single line comments in '// ...' form '#^\s*//(.+)$#m', - + // eliminate multi-line comments in '/* ... */' form, at start of string '#^\s*/\*(.+)\*/#Us', - + // eliminate multi-line comments in '/* ... */' form, at end of string '#/\*(.+)\*/\s*$#Us' - + ), '', $str); - + // eliminate extraneous space return trim($str); } @@ -370,17 +368,17 @@ class TJSON public function decode($str) { $str = $this->reduce_string($str); - + switch (strtolower($str)) { case 'true': return true; case 'false': return false; - + case 'null': return null; - + default: if (is_numeric($str)) { // Lookie-loo, it's a number @@ -393,19 +391,19 @@ class TJSON return ((float)$str == (integer)$str) ? (integer)$str : (float)$str; - + } elseif (preg_match('/^("|\').+(\1)$/s', $str, $m) && $m[1] == $m[2]) { // STRINGS RETURNED IN UTF-8 FORMAT $delim = substr($str, 0, 1); $chrs = substr($str, 1, -1); $utf8 = ''; $strlen_chrs = strlen($chrs); - + for ($c = 0; $c < $strlen_chrs; ++$c) { - + $substr_chrs_c_2 = substr($chrs, $c, 2); $ord_chrs_c = ord($chrs{$c}); - + switch (true) { case $substr_chrs_c_2 == '\b': $utf8 .= chr(0x08); @@ -437,7 +435,7 @@ class TJSON $utf8 .= $chrs{++$c}; } break; - + case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)): // single, escaped unicode character $utf16 = chr(hexdec(substr($chrs, ($c+2), 2))) @@ -445,39 +443,39 @@ class TJSON $utf8 .= $this->utf16be_to_utf8($utf16); $c+=5; break; - + case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F): $utf8 .= $chrs{$c}; break; - + case ($ord_chrs_c & 0xE0) == 0xC0: // characters U-00000080 - U-000007FF, mask 110XXXXX //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $utf8 .= substr($chrs, $c, 2); ++$c; break; - + case ($ord_chrs_c & 0xF0) == 0xE0: // characters U-00000800 - U-0000FFFF, mask 1110XXXX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $utf8 .= substr($chrs, $c, 3); $c += 2; break; - + case ($ord_chrs_c & 0xF8) == 0xF0: // characters U-00010000 - U-001FFFFF, mask 11110XXX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $utf8 .= substr($chrs, $c, 4); $c += 3; break; - + case ($ord_chrs_c & 0xFC) == 0xF8: // characters U-00200000 - U-03FFFFFF, mask 111110XX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $utf8 .= substr($chrs, $c, 5); $c += 4; break; - + case ($ord_chrs_c & 0xFE) == 0xFC: // characters U-04000000 - U-7FFFFFFF, mask 1111110X // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 @@ -488,9 +486,9 @@ class TJSON } } - + return $utf8; - + } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) { // array, or object notation @@ -506,14 +504,14 @@ class TJSON $obj = new stdClass(); } } - + array_push($stk, array('what' => self::JSON_SLICE, 'where' => 0, 'delim' => false)); $chrs = substr($str, 1, -1); $chrs = $this->reduce_string($chrs); - + if ($chrs == '') { if (reset($stk) == self::JSON_IN_ARR) { return $arr; @@ -525,14 +523,14 @@ class TJSON } //print("\nparsing {$chrs}\n"); - + $strlen_chrs = strlen($chrs); - + for ($c = 0; $c <= $strlen_chrs; ++$c) { - + $top = end($stk); $substr_chrs_c_2 = substr($chrs, $c, 2); - + if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == self::JSON_SLICE))) { // found a comma that is not inside a string, array, etc., // OR we've reached the end of the character list @@ -619,16 +617,16 @@ class TJSON // found a comment end, and we're in one now array_pop($stk); $c++; - + for ($i = $top['where']; $i <= $c; ++$i) $chrs = substr_replace($chrs, ' ', $i, 1); - + //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); } - + } - + if (reset($stk) == self::JSON_IN_ARR) { return $arr; @@ -636,11 +634,11 @@ class TJSON return $obj; } - + } } } - + /** * decodes a JSON string into appropriate variable; alias for decode() * @see JSON::decode() @@ -657,7 +655,7 @@ class TJSON { return $this->decode($var); } - + /** * This function returns any UTF-8 encoded text as a list of @@ -667,23 +665,23 @@ class TJSON * @link http://www.randomchaos.com/document.php?source=php_and_unicode * @see unicode_to_utf8() */ - protected function utf8_to_unicode( &$str ) + protected function utf8_to_unicode( &$str ) { - $unicode = array(); + $unicode = array(); $values = array(); $lookingFor = 1; - for ($i = 0; $i < strlen( $str ); $i++ ) + for ($i = 0; $i < strlen( $str ); $i++ ) { $thisValue = ord( $str[ $i ] ); - if ( $thisValue < 128 ) + if ( $thisValue < 128 ) $unicode[] = $thisValue; - else + else { - if ( count( $values ) == 0 ) + if ( count( $values ) == 0 ) $lookingFor = ( $thisValue < 224 ) ? 2 : 3; $values[] = $thisValue; - if ( count( $values ) == $lookingFor ) + if ( count( $values ) == $lookingFor ) { $number = ( $lookingFor == 3 ) ? ( ( $values[0] % 16 ) * 4096 ) + ( ( $values[1] % 64 ) * 64 ) + ( $values[2] % 64 ): @@ -704,21 +702,21 @@ class TJSON * @link http://www.randomchaos.com/document.php?source=php_and_unicode * @see utf8_to_unicode() */ - protected function unicode_to_utf8( &$str ) + protected function unicode_to_utf8( &$str ) { $utf8 = ''; - foreach( $str as $unicode ) + foreach( $str as $unicode ) { - if ( $unicode < 128 ) + if ( $unicode < 128 ) { $utf8.= chr( $unicode ); - } - elseif ( $unicode < 2048 ) + } + elseif ( $unicode < 2048 ) { $utf8.= chr( 192 + ( ( $unicode - ( $unicode % 64 ) ) / 64 ) ); $utf8.= chr( 128 + ( $unicode % 64 ) ); - } - else + } + else { $utf8.= chr( 224 + ( ( $unicode - ( $unicode % 4096 ) ) / 4096 ) ); $utf8.= chr( 128 + ( ( ( $unicode % 4096 ) - ( $unicode % 64 ) ) / 64 ) ); @@ -733,7 +731,7 @@ class TJSON * * Maybe really UCS-2 without mb_string due to utf8_to_unicode limits */ - protected function utf8_to_utf16be(&$str, $bom = false) + protected function utf8_to_utf16be(&$str, $bom = false) { $out = $bom ? "\xFE\xFF" : ''; if(function_exists('mb_convert_encoding')) @@ -750,12 +748,12 @@ class TJSON * * Maybe really UCS-2 without mb_string due to utf8_to_unicode limits */ - protected function utf16be_to_utf8(&$str) + protected function utf16be_to_utf8(&$str) { $uni = unpack('n*',$str); return unicode_to_utf8($uni); } } - + ?> \ No newline at end of file diff --git a/framework/Web/Services/TPageService.php b/framework/Web/Services/TPageService.php index 32f7514c..bb80b902 100644 --- a/framework/Web/Services/TPageService.php +++ b/framework/Web/Services/TPageService.php @@ -16,7 +16,6 @@ Prado::using('System.Web.UI.TPage'); Prado::using('System.Web.UI.TTemplateManager'); Prado::using('System.Web.UI.TThemeManager'); -Prado::using('System.Web.UI.TAssetManager'); /** * TPageService class. @@ -47,10 +46,9 @@ Prado::using('System.Web.UI.TAssetManager'); * Configuration of a module in a subdirectory will overwrite its parent * directory's configuration, if both configurations refer to the same module. * - * By default, TPageService will automatically load three modules: + * By default, TPageService will automatically load two modules: * - {@link TTemplateManager} : manages page and control templates * - {@link TThemeManager} : manages themes used in a Prado application - * - {@link TAssetManager} : manages assets used in a Prado application. * * In page directory configurations, static authorization rules can also be specified, * which governs who and which roles can access particular pages. @@ -121,10 +119,6 @@ class TPageService extends TService * @var boolean whether service is initialized */ private $_initialized=false; - /** - * @var TAssetManager asset manager - */ - private $_assetManager=null; /** * @var TThemeManager theme manager */ @@ -322,27 +316,6 @@ class TPageService extends TService $this->_templateManager=$value; } - /** - * @return TAssetManager asset manager - */ - public function getAssetManager() - { - if(!$this->_assetManager) - { - $this->_assetManager=new TAssetManager; - $this->_assetManager->init(null); - } - return $this->_assetManager; - } - - /** - * @param TAssetManager asset manager - */ - public function setAssetManager(TAssetManager $value) - { - $this->_assetManager=$value; - } - /** * @return TThemeManager theme manager */ @@ -482,19 +455,6 @@ class TPageService extends TService { return $this->getRequest()->constructUrl($this->_id,$pagePath,$getParams,$encodeAmpersand); } - - /** - * Publishes a private asset and returns its URL. - * This method will publish a private asset (file or directory) - * and returns the URL to the asset. Note, if the asset refers to - * a directory, all contents under that directory will be published. - * @param string path of the asset that is either absolute or relative to the directory containing the current running script. - * @return string URL to the asset path. - */ - public function getAsset($path) - { - return $this->getAssetManager()->publishFilePath($path); - } } diff --git a/framework/Web/UI/TAssetManager.php b/framework/Web/UI/TAssetManager.php deleted file mode 100644 index 3e341a5e..00000000 --- a/framework/Web/UI/TAssetManager.php +++ /dev/null @@ -1,239 +0,0 @@ - - * @link http://www.pradosoft.com/ - * @copyright Copyright © 2005 PradoSoft - * @license http://www.pradosoft.com/license/ - * @version $Revision: $ $Date: $ - * @package System.Web.UI - */ - -/** - * TAssetManager class - * - * TAssetManager provides a scheme to allow web clients visiting - * private files that are normally web-inaccessible. - * - * TAssetManager will copy the file to be published into a web-accessible - * directory. The default base directory for storing the file is "assets", which - * should be under the application directory. This can be changed by setting - * the {@link setBasePath BasePath} property together with the - * {@link setBaseUrl BaseUrl} property that refers to the URL for accessing the base path. - * - * By default, TAssetManager will not publish a file or directory if it already - * exists in the publishing directory and has an older modification time. - * If the application mode is set as 'Performance', the modification time check - * will be skipped. You can explicitly require a modification time check - * with the function {@link publishFilePath}. This is usually - * very useful during development. - * - * TAssetManager may be configured in application configuration file within - * page service element as follows, - * - * where {@link getBasePath BasePath} and {@link getBaseUrl BaseUrl} are - * configurable properties of TAssetManager. Make sure that BasePath is a namespace - * pointing to a valid directory writable by the Web server process. - * - * @author Qiang Xue - * @version $Revision: $ $Date: $ - * @package System.Web.UI - * @since 3.0 - */ -class TAssetManager extends TModule -{ - /** - * Default web accessible base path for storing private files - */ - const DEFAULT_BASEPATH='assets'; - /** - * @var string base web accessible path for storing private files - */ - private $_basePath=null; - /** - * @var string base URL for accessing the publishing directory. - */ - private $_baseUrl=null; - /** - * @var boolean whether to use timestamp checking to ensure files are published with up-to-date versions. - */ - private $_checkTimestamp=false; - /** - * @var TApplication application instance - */ - private $_application; - /** - * @var array published assets - */ - private $_published=array(); - /** - * @var boolean whether the module is initialized - */ - private $_initialized=false; - - /** - * Initializes the module. - * This method is required by IModule and is invoked by application. - * @param TXmlElement module configuration - */ - public function init($config) - { - $application=$this->getApplication(); - if($this->_basePath===null) - $this->_basePath=dirname($application->getRequest()->getPhysicalApplicationPath()).'/'.self::DEFAULT_BASEPATH; - if(!is_writable($this->_basePath) || !is_dir($this->_basePath)) - throw new TConfigurationException('assetmanager_basepath_invalid',$this->_basePath); - if($this->_baseUrl===null) - $this->_baseUrl=rtrim(dirname($application->getRequest()->getApplicationPath()),'/\\').'/'.self::DEFAULT_BASEPATH; - $application->getService()->setAssetManager($this); - $this->_initialized=true; - } - - /** - * @return string the root directory storing published asset files - */ - public function getBasePath() - { - return $this->_basePath; - } - - /** - * Sets the root directory storing published asset files. - * The directory must be in namespace format. - * @param string the root directory storing published asset files - * @throws TInvalidOperationException if the service is initialized already - */ - public function setBasePath($value) - { - if($this->_initialized) - throw new TInvalidOperationException('assetmanager_basepath_unchangeable'); - else - { - $this->_basePath=Prado::getPathOfAlias($value); - if($this->_basePath===null || !is_dir($this->_basePath) || !is_writable($this->_basePath)) - throw new TInvalidDataValueException('assetmanage_basepath_invalid',$value); - } - } - - /** - * @return string the base url that the published asset files can be accessed - */ - public function getBaseUrl() - { - return $this->_baseUrl; - } - - /** - * @param string the base url that the published asset files can be accessed - * @throws TInvalidOperationException if the service is initialized already - */ - public function setBaseUrl($value) - { - if($this->_initialized) - throw new TInvalidOperationException('assetmanager_baseurl_unchangeable'); - else - $this->_baseUrl=rtrim($value,'/'); - } - - public function getPublishedUrl($path) - { - if(($fullpath=realpath($path))!==false) - { - $dir=$this->hash(dirname($fullpath)); - $file=$this->_basePath.'/'.$dir.'/'.basename($fullpath); - if(is_file($file) || is_dir($file)) - return $this->_baseUrl.'/'.$dir.'/'.basename($fullpath); - } - return null; - } - - public function isPublished($path) - { - return $this->getPublishedUrl($path) !== null; - } - - /** - * Publishes a file or a directory (recursively). - * This method will copy the content in a directory (recursively) to - * a web accessible directory and returns the URL for the directory. - * @param string the path to be published - * @param boolean whether to use file modify time to ensure every published file is latest - * @return string an absolute URL to the published directory - */ - public function publishFilePath($path,$checkTimestamp=false) - { - if(isset($this->_published[$path])) - return $this->_published[$path]; - else if(($fullpath=realpath($path))===false) - return ''; - else if(is_file($fullpath)) - { - $dir=$this->hash(dirname($fullpath)); - $file=$this->_basePath.'/'.$dir.'/'.basename($fullpath); - if(!is_file($file) || $checkTimestamp || $this->getApplication()->getMode()!==TApplication::STATE_PERFORMANCE) - { - if(!is_dir($this->_basePath.'/'.$dir)) - @mkdir($this->_basePath.'/'.$dir); - if(!is_file($file) || @filemtime($file)<@filemtime($fullpath)) - { - Prado::trace("Publishing file $fullpath",'System.Web.UI.TAssetManager'); - @copy($fullpath,$file); - } - } - $this->_published[$path]=$this->_baseUrl.'/'.$dir.'/'.basename($fullpath); - return $this->_published[$path]; - } - else - { - $dir=$this->hash($fullpath); - if(!is_dir($this->_basePath.'/'.$dir) || $checkTimestamp || $this->getApplication()->getMode()!==TApplication::STATE_PERFORMANCE) - { - Prado::trace("Publishing directory $fullpath",'System.Web.UI.TAssetManager'); - $this->copyDirectory($fullpath,$this->_basePath.'/'.$dir); - } - $this->_published[$path]=$this->_baseUrl.'/'.$dir; - return $this->_published[$path]; - } - } - - /** - * Generate a CRC32 hash for the directory path. Collisions are higher - * than MD5 but generates a much smaller hash string. - * @param string string to be hashed. - * @return string hashed string. - */ - protected function hash($dir) - { - return sprintf('%x',crc32($dir)); - } - - /** - * Copies a directory recursively as another. - * If the destination directory does not exist, it will be created. - * File modification time is used to ensure the copied files are latest. - * @param string the source directory - * @param string the destination directory - */ - protected function copyDirectory($src,$dst) - { - if(!is_dir($dst)) - @mkdir($dst); - $folder=@opendir($src); - while($file=@readdir($folder)) - { - if($file==='.' || $file==='..') - continue; - else if(is_file($src.'/'.$file)) - { - if(@filemtime($dst.'/'.$file)<@filemtime($src.'/'.$file)) - @copy($src.'/'.$file,$dst.'/'.$file); - } - else - $this->copyDirectory($src.'/'.$file,$dst.'/'.$file); - } - closedir($folder); - } -} - -?> \ No newline at end of file diff --git a/framework/Web/UI/TClientScriptManager.php b/framework/Web/UI/TClientScriptManager.php index 0ff99aa2..1ea4175d 100644 --- a/framework/Web/UI/TClientScriptManager.php +++ b/framework/Web/UI/TClientScriptManager.php @@ -10,76 +10,6 @@ * @package System.Web.UI */ -/*class TPostBackOptions extends TComponent -{ - public $_actionUrl=''; - public $_autoPostBack=false; - public $_clientSubmit=true; - public $_performValidation=false; - public $_validationGroup=''; - public $_trackFocus=false; - - public function getActionUrl() - { - return $this->_actionUrl; - } - - public function setActionUrl($value) - { - $this->_actionUrl=THttpUtility::quoteJavaScriptString($value); - } - - public function getAutoPostBack() - { - return $this->_autoPostBack; - } - - public function setAutoPostBack($value) - { - $this->_autoPostBack=$value; - } - - public function getClientSubmit() - { - return $this->_clientSubmit; - } - - public function setClientSubmit($value) - { - $this->_clientSubmit=$value; - } - - public function getPerformValidation() - { - return $this->_performValidation; - } - - public function setPerformValidation($value) - { - $this->_performValidation=$value; - } - - public function getValidationGroup() - { - return $this->_validationGroup; - } - - public function setValidationGroup($value) - { - $this->_validationGroup=$value; - } - - public function getTrackFocus() - { - return $this->_trackFocus; - } - - public function setTrackFocus($value) - { - $this->_trackFocus=$value; - } -} -*/ Prado::using('System.Web.Javascripts.*'); /** @@ -94,21 +24,21 @@ class TClientScriptManager extends TComponent { const SCRIPT_DIR='Web/Javascripts/js'; //const POSTBACK_FUNC='Prado.doPostBack'; - + private $_page; private $_hiddenFields=array(); private $_beginScripts=array(); private $_endScripts=array(); private $_scriptFiles=array(); - + //private $_headScriptFiles=array(); //private $_headScripts=array(); - + private $_styleSheetFiles=array(); private $_styleSheets=array(); - + private $_client; - + /*private $_onSubmitStatements=array(); private $_arrayDeclares=array(); private $_expandoAttributes=array(); @@ -116,17 +46,17 @@ class TClientScriptManager extends TComponent private $_focusScriptRegistered=false; private $_scrollScriptRegistered=false; */ - + private $_publishedScriptFiles=array(); - + public function __construct(TPage $owner) { $this->_page=$owner; $this->_client = new TClientScript($this); } - - + + public function registerPostBackControl($control,$namespace='Prado.WebUI') { $options = $this->getPostBackOptions($control); @@ -134,7 +64,7 @@ class TClientScriptManager extends TComponent $namespace = empty($namespace) ? "window" : $namespace; $code = "new {$namespace}.{$type}($options);"; $this->registerEndScript(sprintf('%08X', crc32($code)), $code); - + $this->registerHiddenField(TPage::FIELD_POSTBACK_TARGET,''); $this->registerHiddenField(TPage::FIELD_POSTBACK_PARAMETER,''); $this->registerClientScript('prado'); @@ -143,7 +73,7 @@ class TClientScriptManager extends TComponent protected function getPostBackOptions($control) { $postback = $control->getPostBackOptions(); - if(!isset($postback['ID'])) + if(!isset($postback['ID'])) $postback['ID'] = $control->getClientID(); if(!isset($postback['FormID'])) $postback['FormID'] = $this->_page->getForm()->getClientID(); @@ -152,7 +82,7 @@ class TClientScriptManager extends TComponent } /** - * Register a default button to panel. When the $panel is in focus and + * Register a default button to panel. When the $panel is in focus and * the 'enter' key is pressed, the $button will be clicked. * @param TControl panel to register the default button action * @param TControl button to trigger a postback @@ -180,12 +110,12 @@ class TClientScriptManager extends TComponent /** - * Register client scripts. + * Register client scripts. */ public function registerClientScript($script) { static $scripts = array(); - $scripts = array_unique(array_merge($scripts, + $scripts = array_unique(array_merge($scripts, TClientScript::getScripts($script))); $this->publishClientScriptAssets($scripts); @@ -209,9 +139,8 @@ class TClientScriptManager extends TComponent { $base = Prado::getFrameworkPath(); $clientScripts = self::SCRIPT_DIR; - $assetManager = $this->_page->getService()->getAssetManager(); $file = "{$base}/{$clientScripts}/{$lib}.js"; - $assetManager->publishFilePath($file); + $this->publishFilePath($file); $this->_publishedScriptFiles[$lib] = true; } } @@ -229,9 +158,8 @@ class TClientScriptManager extends TComponent { $base = Prado::getFrameworkPath(); $clientScripts = self::SCRIPT_DIR; - $assetManager = $this->_page->getService()->getAssetManager(); $file = "{$base}/{$clientScripts}/{$scriptFile}"; - $url= $assetManager->publishFilePath($file); + $url= $this->publishFilePath($file); $this->_publishedScriptFiles[$scriptFile] = $url; return $url; } @@ -485,7 +413,7 @@ class TClientScriptManager extends TComponent { return ""; } - + public function renderStyleSheetFiles($writer) { $str=''; @@ -535,4 +463,204 @@ class TClientScriptManager extends TComponent */ } +/** + * PradoClientScript class. + * + * Resolves Prado client script dependencies. e.g. TPradoClientScript::getScripts("dom"); + * + * - base basic javascript utilities, e.g. $() + * - dom DOM and Form functions, e.g. $F(inputID) to retrive form input values. + * - effects Effects such as fade, shake, move + * - controls Prado client-side components, e.g. Slider, AJAX components + * - validator Prado client-side validators. + * - ajax Prado AJAX library including Prototype's AJAX and JSON. + * + * Dependencies for each library are automatically resolved. + * + * Namespace: System.Web.UI + * + * @author Wei Zhuo + * @version $Revision: 1.1 $ $Date: 2005/11/06 23:02:33 $ + * @package System.Web.UI + */ +class TPradoClientScript +{ + /** + * Client-side javascript library dependencies + * @var array + */ + protected static $_dependencies = array( + 'prado' => array('prado'), + 'effects' => array('prado', 'effects'), + 'ajax' => array('prado', 'effects', 'ajax'), + 'validator' => array('prado', 'validator'), + 'logger' => array('prado', 'logger'), + 'datepicker' => array('prado', 'datepicker'), + 'rico' => array('prado', 'effects', 'ajax', 'rico'), + 'colorpicker' => array('prado', 'colorpicker') + ); + + /** + * Resolve dependencies for the given library name(s). + * @param string|array name(s) of the library to be loaded. + * @return array list of library file names (w/o extension) for the specified library name(s). + */ + public function getScripts($scripts) + { + $files = array(); + if(!is_array($scripts)) $scripts = array($scripts); + foreach($scripts as $script) + { + if(isset(self::$_dependencies[$script])) + $files = array_merge($files, self::$_dependencies[$script]); + $files[] = $script; + } + $files = array_unique($files); + return $files; + } + + + /** + * TODO: clean up + * + public function getPostBackEventReference($control,$parameter='',$options=null,$javascriptPrefix=true) + { + if(!$options || (!$options->getPerformValidation() && !$options->getTrackFocus() && $options->getClientSubmit() && $options->getActionUrl()=='')) + { + $this->registerPostBackScript(); + if(($form=$this->_page->getForm())!==null) + $formID=$form->getClientID(); + else + throw new TConfigurationException('clientscriptmanager_form_required'); + $postback=self::POSTBACK_FUNC.'(\''.$formID.'\',\''.$control->getUniqueID().'\',\''.THttpUtility::quoteJavaScriptString($parameter).'\')'; + if($options && $options->getAutoPostBack()) + $postback='setTimeout(\''.THttpUtility::quoteJavaScriptString($postback).'\',0)'; + return $javascriptPrefix?'javascript:'.$postback:$postback; + } + $opt=''; + $flag=false; + if($options->getPerformValidation()) + { + $flag=true; + $this->registerValidationScript(); + $opt.=',true,'; + } + else + $opt.=',false,'; + if($options->getValidationGroup()!=='') + { + $flag=true; + $opt.='"'.$options->getValidationGroup().'",'; + } + else + $opt.='\'\','; + if($options->getActionUrl()!=='') + { + $flag=true; + $this->_page->setCrossPagePostBack(true); + $opt.='"'.$options->getActionUrl().'",'; + } + else + $opt.='null,'; + if($options->getTrackFocus()) + { + $flag=true; + $this->registerFocusScript(); + $opt.='true,'; + } + else + $opt.='false,'; + if($options->getClientSubmit()) + { + $flag=true; + $opt.='true'; + } + else + $opt.='false'; + if(!$flag) + return ''; + $this->registerPostBackScript(); + if(($form=$this->_page->getForm())!==null) + $formID=$form->getClientID(); + else + throw new TConfigurationException('clientscriptmanager_form_required'); + $postback=self::POSTBACK_FUNC.'(\''.$formID.'\',\''.$control->getUniqueID().'\',\''.THttpUtility::quoteJavaScriptString($parameter).'\''.$opt.')'; + if($options && $options->getAutoPostBack()) + $postback='setTimeout(\''.THttpUtility::quoteJavaScriptString($postback).'\',0)'; + return $javascriptPrefix?'javascript:'.$postback:$postback; + }*/ + +} + +/*class TPostBackOptions extends TComponent +{ + public $_actionUrl=''; + public $_autoPostBack=false; + public $_clientSubmit=true; + public $_performValidation=false; + public $_validationGroup=''; + public $_trackFocus=false; + + public function getActionUrl() + { + return $this->_actionUrl; + } + + public function setActionUrl($value) + { + $this->_actionUrl=THttpUtility::quoteJavaScriptString($value); + } + + public function getAutoPostBack() + { + return $this->_autoPostBack; + } + + public function setAutoPostBack($value) + { + $this->_autoPostBack=$value; + } + + public function getClientSubmit() + { + return $this->_clientSubmit; + } + + public function setClientSubmit($value) + { + $this->_clientSubmit=$value; + } + + public function getPerformValidation() + { + return $this->_performValidation; + } + + public function setPerformValidation($value) + { + $this->_performValidation=$value; + } + + public function getValidationGroup() + { + return $this->_validationGroup; + } + + public function setValidationGroup($value) + { + $this->_validationGroup=$value; + } + + public function getTrackFocus() + { + return $this->_trackFocus; + } + + public function setTrackFocus($value) + { + $this->_trackFocus=$value; + } +} +*/ + ?> \ No newline at end of file diff --git a/framework/Web/UI/TControl.php b/framework/Web/UI/TControl.php index 49ba629f..4f905a1a 100644 --- a/framework/Web/UI/TControl.php +++ b/framework/Web/UI/TControl.php @@ -296,21 +296,6 @@ class TControl extends TComponent return $this->getPage(); } - /** - * Publishes a private asset and gets its URL. - * This method will publish a private asset (file or directory) - * and gets the URL to the asset. Note, if the asset refers to - * a directory, all contents under that directory will be published. - * @param string path of the asset that is relative to the directory containing the control class file. - * @return string URL to the asset path. - */ - public function getAsset($assetPath) - { - $class=new ReflectionClass(get_class($this)); - $assetPath=dirname($class->getFileName()).'/'.$assetPath; - return $this->getService()->getAsset($assetPath); - } - /** * Returns the id of the control. * Control ID can be either manually set or automatically generated. diff --git a/framework/Web/UI/TTemplateManager.php b/framework/Web/UI/TTemplateManager.php index 4c71de51..67bda1b2 100644 --- a/framework/Web/UI/TTemplateManager.php +++ b/framework/Web/UI/TTemplateManager.php @@ -182,10 +182,6 @@ class TTemplate extends TComponent implements ITemplate * @var string template file path (if available) */ private $_tplFile=null; - /** - * @var TAssetManager asset manager - */ - private $_assetManager; /** * @var integer the line number that parsing starts from (internal use) */ @@ -264,7 +260,6 @@ class TTemplate extends TComponent implements ITemplate { if(($page=$tplControl->getPage())===null) $page=$this->getService()->getRequestedPage(); - $this->_assetManager=$this->getService()->getAssetManager(); $controls=array(); foreach($this->_tpl as $key=>$object) { @@ -376,7 +371,7 @@ class TTemplate extends TComponent implements ITemplate $component->$setter($value[1]); break; case self::CONFIG_ASSET: // asset URL - $url=$this->_assetManager->publishFilePath($this->_contextPath.'/'.$value[1]); + $url=$this->publishFilePath($this->_contextPath.'/'.$value[1]); $component->$setter($url); break; case self::CONFIG_PARAMETER: // application parameter @@ -416,7 +411,7 @@ class TTemplate extends TComponent implements ITemplate $component->setSubProperty($name,$value[1]); break; case self::CONFIG_ASSET: // asset URL - $url=$this->_assetManager->publishFilePath($this->_contextPath.'/'.$value[1]); + $url=$this->publishFilePath($this->_contextPath.'/'.$value[1]); $component->setSubProperty($name,$url); break; case self::CONFIG_PARAMETER: // application parameter diff --git a/framework/Web/UI/WebControls/TColorPicker.php b/framework/Web/UI/WebControls/TColorPicker.php index f168aa5f..2a19125b 100644 --- a/framework/Web/UI/WebControls/TColorPicker.php +++ b/framework/Web/UI/WebControls/TColorPicker.php @@ -133,7 +133,7 @@ class TColorPicker extends TTextBox $cs = $this->getPage()->getClientScript(); $style = 'System.Web.Javascripts.colorpicker.'.$this->getColorPickerStyle(); $cssFile=Prado::getPathOfNamespace($style,'.css'); - $url = $this->getService()->getAsset($cssFile); + $url = $this->publishFilePath($cssFile); if(!$cs->isStyleSheetFileRegistered($style)) $cs->registerStyleSheetFile($style, $url); return $url; @@ -158,7 +158,7 @@ class TColorPicker extends TTextBox { $image = 'System.Web.Javascripts.colorpicker.'.$filename; $file = Prado::getPathOfNamespace($image, $ext); - $list[$filename.$ext] = $this->getService()->getAsset($file); + $list[$filename.$ext] = $this->publishFilePath($file); } $imgs['button.gif'] = $list['button.gif']; $imgs['background.png'] = $list['background.png']; diff --git a/framework/Web/UI/WebControls/TDatePicker.php b/framework/Web/UI/WebControls/TDatePicker.php index e7e68f6f..6f5eaffb 100644 --- a/framework/Web/UI/WebControls/TDatePicker.php +++ b/framework/Web/UI/WebControls/TDatePicker.php @@ -330,7 +330,7 @@ class TDatePicker extends TTextBox $cs = $this->getPage()->getClientScript(); $image = 'System.Web.Javascripts.datepicker.calendar'; $file = Prado::getPathOfNamespace($image, '.png'); - return $this->getService()->getAsset($file); + return $this->publishFilePath($file); } /** @@ -342,7 +342,7 @@ class TDatePicker extends TTextBox $cs = $this->getPage()->getClientScript(); $style = 'System.Web.Javascripts.datepicker.'.$this->getCalendarStyle(); $cssFile=Prado::getPathOfNamespace($style,'.css'); - $url = $this->getService()->getAsset($cssFile); + $url = $this->publishFilePath($cssFile); if(!$cs->isStyleSheetFileRegistered($style)) $cs->registerStyleSheetFile($style, $url); return $url; diff --git a/framework/Web/UI/WebControls/TRatingList.php b/framework/Web/UI/WebControls/TRatingList.php index 6613c08b..3c5a9279 100644 --- a/framework/Web/UI/WebControls/TRatingList.php +++ b/framework/Web/UI/WebControls/TRatingList.php @@ -80,22 +80,22 @@ class TRatingList extends TRadioButtonList { $cs = $this->getPage()->getClientScript(); $style = $this->getRatingStyle()->getStyleSheet(); - $url = $this->getService()->getAsset($style); + $url = $this->publishFilePath($style); if(!$cs->isStyleSheetFileRegistered($style)) - $cs->registerStyleSheetFile($style, $url); + $cs->registerStyleSheetFile($style, $url); return $url; } - + protected function publishRatingListAssets() { $cs = $this->getPage()->getClientScript(); $assets = $this->getRatingStyle()->getAssets(); $list = array(); foreach($assets as $file) - $list[] = $this->getService()->getAsset($file); + $list[] = $this->publishFilePath($file); return $list; } - + /** * @param THtmlWriter writer */ @@ -146,7 +146,7 @@ abstract class TRatingListStyle } class TRatingListDefaultStyle extends TRatingListStyle -{ +{ public function __construct() { parent::__construct(); diff --git a/framework/Web/UI/WebControls/TTextHighlighter.php b/framework/Web/UI/WebControls/TTextHighlighter.php index 80358ff6..281f131e 100644 --- a/framework/Web/UI/WebControls/TTextHighlighter.php +++ b/framework/Web/UI/WebControls/TTextHighlighter.php @@ -123,7 +123,7 @@ class TTextHighlighter extends TWebControl if(!$cs->isStyleSheetFileRegistered($cssKey)) { $cssFile=Prado::getPathOfNamespace('System.3rdParty.geshi.highlight','.css'); - $styleSheet = $this->getService()->getAsset($cssFile); + $styleSheet = $this->publishFilePath($cssFile); $cs->registerStyleSheetFile($cssKey, $styleSheet); } } -- cgit v1.2.3