/protected/test.txt
http://github.com/phpnode/YiiJS · Plain Text · 26755 lines · 25815 code · 940 blank · 0 comment · 0 complexity · 29c971761f8a835f00acf162c4fa918b MD5 · raw file
- /*global php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * Yii is a helper class serving common framework functionalities.
- *
- * It encapsulates {@link YiiBase} which provides the actual implementation.
- * By writing your own Yii class, you can customize some functionalities of YiiBase.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: yii.js 2799 2011-01-01 19:31:13Z qiang.xue $
- * @package system
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.YiiBase
- */
- var YII_DEBUG = true, YII_TRACE_LEVEL = 3, YII_BEGIN_TIME = new Date().getTime() / 1000, Yii = /** @lends Yii.prototype */{
- /**
- * @property {Array} class map used by the Yii autoloading mechanism.
- * The array keys are the class names and the array values are the corresponding class file paths.
- * @since 1.1.5
- */
- classMap: {},
- _aliases: {},
- _imports: {},
- _includePaths: {},
- _app: null,
- _logger: null,
- /**
- * @property {Array} class map for core Yii classes.
- * NOTE, DO NOT MODIFY THIS ARRAY MANUALLY. IF YOU CHANGE OR ADD SOME CORE CLASSES,
- * PLEASE RUN 'build autoload' COMMAND TO UPDATE THIS ARRAY.
- */
- _coreClasses: {'CApplication':'/base/CApplication.js','CApplicationComponent':'/base/CApplicationComponent.js','CBehavior':'/base/CBehavior.js','CComponent':'/base/CComponent.js','CErrorEvent':'/base/CErrorEvent.js','CErrorHandler':'/base/CErrorHandler.js','CException':'/base/CException.js','CExceptionEvent':'/base/CExceptionEvent.js','CHttpException':'/base/CHttpException.js','CModel':'/base/CModel.js','CModelBehavior':'/base/CModelBehavior.js','CModelEvent':'/base/CModelEvent.js','CModule':'/base/CModule.js','CSecurityManager':'/base/CSecurityManager.js','CStatePersister':'/base/CStatePersister.js','CApcCache':'/caching/CApcCache.js','CCache':'/caching/CCache.js','CDbCache':'/caching/CDbCache.js','CDummyCache':'/caching/CDummyCache.js','CEAcceleratorCache':'/caching/CEAcceleratorCache.js','CFileCache':'/caching/CFileCache.js','CMemCache':'/caching/CMemCache.js','CWinCache':'/caching/CWinCache.js','CXCache':'/caching/CXCache.js','CZendDataCache':'/caching/CZendDataCache.js','CCacheDependency':'/caching/dependencies/CCacheDependency.js','CChainedCacheDependency':'/caching/dependencies/CChainedCacheDependency.js','CDbCacheDependency':'/caching/dependencies/CDbCacheDependency.js','CDirectoryCacheDependency':'/caching/dependencies/CDirectoryCacheDependency.js','CExpressionDependency':'/caching/dependencies/CExpressionDependency.js','CFileCacheDependency':'/caching/dependencies/CFileCacheDependency.js','CGlobalStateCacheDependency':'/caching/dependencies/CGlobalStateCacheDependency.js','CAttributeCollection':'/collections/CAttributeCollection.js','CConfiguration':'/collections/CConfiguration.js','CList':'/collections/CList.js','CListIterator':'/collections/CListIterator.js','CMap':'/collections/CMap.js','CMapIterator':'/collections/CMapIterator.js','CQueue':'/collections/CQueue.js','CQueueIterator':'/collections/CQueueIterator.js','CStack':'/collections/CStack.js','CStackIterator':'/collections/CStackIterator.js','CTypedList':'/collections/CTypedList.js','CTypedMap':'/collections/CTypedMap.js','CConsoleApplication':'/console/CConsoleApplication.js','CConsoleCommand':'/console/CConsoleCommand.js','CConsoleCommandRunner':'/console/CConsoleCommandRunner.js','CHelpCommand':'/console/CHelpCommand.js','CDbCommand':'/db/CDbCommand.js','CDbConnection':'/db/CDbConnection.js','CDbDataReader':'/db/CDbDataReader.js','CDbException':'/db/CDbException.js','CDbMigration':'/db/CDbMigration.js','CDbTransaction':'/db/CDbTransaction.js','CActiveFinder':'/db/ar/CActiveFinder.js','CActiveRecord':'/db/ar/CActiveRecord.js','CActiveRecordBehavior':'/db/ar/CActiveRecordBehavior.js','CDbColumnSchema':'/db/schema/CDbColumnSchema.js','CDbCommandBuilder':'/db/schema/CDbCommandBuilder.js','CDbCriteria':'/db/schema/CDbCriteria.js','CDbExpression':'/db/schema/CDbExpression.js','CDbSchema':'/db/schema/CDbSchema.js','CDbTableSchema':'/db/schema/CDbTableSchema.js','CMssqlColumnSchema':'/db/schema/mssql/CMssqlColumnSchema.js','CMssqlCommandBuilder':'/db/schema/mssql/CMssqlCommandBuilder.js','CMssqlPdoAdapter':'/db/schema/mssql/CMssqlPdoAdapter.js','CMssqlSchema':'/db/schema/mssql/CMssqlSchema.js','CMssqlTableSchema':'/db/schema/mssql/CMssqlTableSchema.js','CMysqlColumnSchema':'/db/schema/mysql/CMysqlColumnSchema.js','CMysqlSchema':'/db/schema/mysql/CMysqlSchema.js','CMysqlTableSchema':'/db/schema/mysql/CMysqlTableSchema.js','COciColumnSchema':'/db/schema/oci/COciColumnSchema.js','COciCommandBuilder':'/db/schema/oci/COciCommandBuilder.js','COciSchema':'/db/schema/oci/COciSchema.js','COciTableSchema':'/db/schema/oci/COciTableSchema.js','CPgsqlColumnSchema':'/db/schema/pgsql/CPgsqlColumnSchema.js','CPgsqlSchema':'/db/schema/pgsql/CPgsqlSchema.js','CPgsqlTableSchema':'/db/schema/pgsql/CPgsqlTableSchema.js','CSqliteColumnSchema':'/db/schema/sqlite/CSqliteColumnSchema.js','CSqliteCommandBuilder':'/db/schema/sqlite/CSqliteCommandBuilder.js','CSqliteSchema':'/db/schema/sqlite/CSqliteSchema.js','CChoiceFormat':'/i18n/CChoiceFormat.js','CDateFormatter':'/i18n/CDateFormatter.js','CDbMessageSource':'/i18n/CDbMessageSource.js','CGettextMessageSource':'/i18n/CGettextMessageSource.js','CLocale':'/i18n/CLocale.js','CMessageSource':'/i18n/CMessageSource.js','CNumberFormatter':'/i18n/CNumberFormatter.js','CPhpMessageSource':'/i18n/CPhpMessageSource.js','CGettextFile':'/i18n/gettext/CGettextFile.js','CGettextMoFile':'/i18n/gettext/CGettextMoFile.js','CGettextPoFile':'/i18n/gettext/CGettextPoFile.js','CDbLogRoute':'/logging/CDbLogRoute.js','CEmailLogRoute':'/logging/CEmailLogRoute.js','CFileLogRoute':'/logging/CFileLogRoute.js','CLogFilter':'/logging/CLogFilter.js','CLogRoute':'/logging/CLogRoute.js','CLogRouter':'/logging/CLogRouter.js','CLogger':'/logging/CLogger.js','CProfileLogRoute':'/logging/CProfileLogRoute.js','CWebLogRoute':'/logging/CWebLogRoute.js','CDateTimeParser':'/utils/CDateTimeParser.js','CFileHelper':'/utils/CFileHelper.js','CFormatter':'/utils/CFormatter.js','CMarkdownParser':'/utils/CMarkdownParser.js','CPropertyValue':'/utils/CPropertyValue.js','CTimestamp':'/utils/CTimestamp.js','CVarDumper':'/utils/CVarDumper.js','CBooleanValidator':'/validators/CBooleanValidator.js','CCaptchaValidator':'/validators/CCaptchaValidator.js','CCompareValidator':'/validators/CCompareValidator.js','CDateValidator':'/validators/CDateValidator.js','CDefaultValueValidator':'/validators/CDefaultValueValidator.js','CEmailValidator':'/validators/CEmailValidator.js','CExistValidator':'/validators/CExistValidator.js','CFileValidator':'/validators/CFileValidator.js','CFilterValidator':'/validators/CFilterValidator.js','CInlineValidator':'/validators/CInlineValidator.js','CNumberValidator':'/validators/CNumberValidator.js','CRangeValidator':'/validators/CRangeValidator.js','CRegularExpressionValidator':'/validators/CRegularExpressionValidator.js','CRequiredValidator':'/validators/CRequiredValidator.js','CSafeValidator':'/validators/CSafeValidator.js','CStringValidator':'/validators/CStringValidator.js','CTypeValidator':'/validators/CTypeValidator.js','CUniqueValidator':'/validators/CUniqueValidator.js','CUnsafeValidator':'/validators/CUnsafeValidator.js','CUrlValidator':'/validators/CUrlValidator.js','CValidator':'/validators/CValidator.js','CActiveDataProvider':'/web/CActiveDataProvider.js','CArrayDataProvider':'/web/CArrayDataProvider.js','CAssetManager':'/web/CAssetManager.js','CBaseController':'/web/CBaseController.js','CCacheHttpSession':'/web/CCacheHttpSession.js','CClientScript':'/web/CClientScript.js','CController':'/web/CController.js','CDataProvider':'/web/CDataProvider.js','CDbHttpSession':'/web/CDbHttpSession.js','CExtController':'/web/CExtController.js','CFormModel':'/web/CFormModel.js','CHttpCookie':'/web/CHttpCookie.js','CHttpRequest':'/web/CHttpRequest.js','CHttpSession':'/web/CHttpSession.js','CHttpSessionIterator':'/web/CHttpSessionIterator.js','COutputEvent':'/web/COutputEvent.js','CPagination':'/web/CPagination.js','CSort':'/web/CSort.js','CSqlDataProvider':'/web/CSqlDataProvider.js','CTheme':'/web/CTheme.js','CThemeManager':'/web/CThemeManager.js','CUploadedFile':'/web/CUploadedFile.js','CUrlManager':'/web/CUrlManager.js','CWebApplication':'/web/CWebApplication.js','CWebModule':'/web/CWebModule.js','CWidgetFactory':'/web/CWidgetFactory.js','CAction':'/web/actions/CAction.js','CInlineAction':'/web/actions/CInlineAction.js','CViewAction':'/web/actions/CViewAction.js','CAccessControlFilter':'/web/auth/CAccessControlFilter.js','CAuthAssignment':'/web/auth/CAuthAssignment.js','CAuthItem':'/web/auth/CAuthItem.js','CAuthManager':'/web/auth/CAuthManager.js','CBaseUserIdentity':'/web/auth/CBaseUserIdentity.js','CDbAuthManager':'/web/auth/CDbAuthManager.js','CPhpAuthManager':'/web/auth/CPhpAuthManager.js','CUserIdentity':'/web/auth/CUserIdentity.js','CWebUser':'/web/auth/CWebUser.js','CFilter':'/web/filters/CFilter.js','CFilterChain':'/web/filters/CFilterChain.js','CInlineFilter':'/web/filters/CInlineFilter.js','CForm':'/web/form/CForm.js','CFormButtonElement':'/web/form/CFormButtonElement.js','CFormElement':'/web/form/CFormElement.js','CFormElementCollection':'/web/form/CFormElementCollection.js','CFormInputElement':'/web/form/CFormInputElement.js','CFormStringElement':'/web/form/CFormStringElement.js','CGoogleApi':'/web/helpers/CGoogleApi.js','CHtml':'/web/helpers/CHtml.js','CJSON':'/web/helpers/CJSON.js','CJavaScript':'/web/helpers/CJavaScript.js','CPradoViewRenderer':'/web/renderers/CPradoViewRenderer.js','CViewRenderer':'/web/renderers/CViewRenderer.js','CWebService':'/web/services/CWebService.js','CWebServiceAction':'/web/services/CWebServiceAction.js','CWsdlGenerator':'/web/services/CWsdlGenerator.js','CActiveForm':'/web/widgets/CActiveForm.js','CAutoComplete':'/web/widgets/CAutoComplete.js','CClipWidget':'/web/widgets/CClipWidget.js','CContentDecorator':'/web/widgets/CContentDecorator.js','CFilterWidget':'/web/widgets/CFilterWidget.js','CFlexWidget':'/web/widgets/CFlexWidget.js','CHtmlPurifier':'/web/widgets/CHtmlPurifier.js','CInputWidget':'/web/widgets/CInputWidget.js','CMarkdown':'/web/widgets/CMarkdown.js','CMaskedTextField':'/web/widgets/CMaskedTextField.js','CMultiFileUpload':'/web/widgets/CMultiFileUpload.js','COutputCache':'/web/widgets/COutputCache.js','COutputProcessor':'/web/widgets/COutputProcessor.js','CStarRating':'/web/widgets/CStarRating.js','CTabView':'/web/widgets/CTabView.js','CTextHighlighter':'/web/widgets/CTextHighlighter.js','CTreeView':'/web/widgets/CTreeView.js','CWidget':'/web/widgets/CWidget.js','CCaptcha':'/web/widgets/captcha/CCaptcha.js','CCaptchaAction':'/web/widgets/captcha/CCaptchaAction.js','CBasePager':'/web/widgets/pagers/CBasePager.js','CLinkPager':'/web/widgets/pagers/CLinkPager.js','CListPager':'/web/widgets/pagers/CListPager.js'},
- /**
- * Augments a class with properties from another class
- * @param {Object} receivingClass The class that should be augmented
- * @param {Object} givingClass The class that donates the properties
- */
- augment: function (receivingClass, givingClass) {
- var methodName;
- for (methodName in givingClass.prototype) {
- if(!receivingClass.prototype[methodName]) {
- receivingClass.prototype[methodName] = givingClass.prototype[methodName];
- }
- }
- },
-
- /**
- * @returns {String} the version of Yii framework
- */
- getVersion: function () {
- return '1.1.8-dev';
- },
- /**
- * Creates a Web application instance.
- * @param {Mixed} config application configuration.
- * If a string, it is treated as the path of the file that contains the configuration;
- * If an array, it is the actual configuration information.
- * Please make sure you specify the {@link CApplication::basePath basePath} property in the configuration,
- * which should point to the directory containing all application logic, template and data.
- * If not, the directory will be defaulted to 'protected'.
- */
- createWebApplication: function (config) {
- if (config === undefined) {
- config = null;
- }
- return Yii.createApplication('CWebApplication',config);
- },
- /**
- * Creates a console application instance.
- * @param {Mixed} config application configuration.
- * If a string, it is treated as the path of the file that contains the configuration;
- * If an array, it is the actual configuration information.
- * Please make sure you specify the {@link CApplication::basePath basePath} property in the configuration,
- * which should point to the directory containing all application logic, template and data.
- * If not, the directory will be defaulted to 'protected'.
- */
- createConsoleApplication: function (config) {
- if (config === undefined) {
- config = null;
- }
- return Yii.createApplication('CConsoleApplication',config);
- },
- /**
- * Creates an application of the specified class.
- * @param {String} classVar the application class name
- * @param {Mixed} config application configuration. This parameter will be passed as the parameter
- * to the constructor of the application class.
- * @returns {Mixed} the application instance
- * @since 1.0.10
- */
- createApplication: function (classVar, config) {
- if (config === undefined) {
- config = null;
- }
-
- return new Yii[classVar](config);
-
- },
- /**
- * Returns the application singleton, null if the singleton has not been created yet.
- * @returns {Yii.CApplication} the application singleton, null if the singleton has not been created yet.
- */
- app: function () {
- return Yii._app;
- },
- /**
- * Stores the application instance in the class static member.
- * This method helps implement a singleton pattern for CApplication.
- * Repeated invocation of this method or the CApplication constructor
- * will cause the throw of an exception.
- * To retrieve the application instance, use {@link app()}.
- * @param {Yii.CApplication} app the application instance. If this is null, the existing
- * application singleton will be removed.
- * @throws {Yii.CException} if multiple application instances are registered.
- */
- setApplication: function (app) {
- var _app;
- if(Yii._app===null || app===null) {
- Yii._app=app;
- }
- else {
- throw new Yii.CException(Yii.t('yii','Yii application can only be created once.'));
- }
- },
- /**
- * @returns {String} the path of the framework
- */
- getFrameworkPath: function () {
- return YII_PATH;
- },
- /**
- * Creates an object and initializes it based on the given configuration.
- *
- * The specified configuration can be either a string or an array.
- * If the former, the string is treated as the object type which can
- * be either the class name or {@link Yii::getPathOfAlias class path alias}.
- * If the latter, the 'class' element is treated as the object type,
- * and the rest name-value pairs in the array are used to initialize
- * the corresponding object properties.
- *
- * Any additional parameters passed to this method will be
- * passed to the constructor of the object being created.
- *
- * NOTE: the array-typed configuration has been supported since version 1.0.1.
- *
- * @param {Mixed} config the configuration. It can be either a string or an array.
- * @returns {Mixed} the created object
- * @throws {Yii.CException} if the configuration does not have a 'class' element.
- */
- createComponent: function (config) {
- var type, n, args, object, classVar, key, value;
-
- if(typeof(config) === 'string') {
- type=config;
- config=[];
- }
- else if(config['class'] !== undefined) {
- type=config['class'];
- delete config['class'];
- }
- else {
- throw new Yii.CException(Yii.t('yii','Object configuration must be an array containing a "class" element.'));
- }
- if(!Yii[type]) {
- type=Yii.imports(type,true);
- }
- if((n=arguments.length)>1) {
- args=arguments;
- if(n===2) {
- object=new Yii[type](args[1]);
- }
- else if(n===3) {
- object=new Yii[type](args[1],args[2]);
- }
- else if(n===4) {
- object=new Yii[type](args[1],args[2],args[3]);
- }
- else if(n===4) {
- object=new Yii[type](args[1],args[2],args[3]);
- }
- else if(n===5) {
- object=new Yii[type](args[1],args[2],args[3],args[4]);
- }
- }
- else {
- object=new Yii[type]();
- }
-
- for (key in config) {
- if (config.hasOwnProperty(key)) {
-
- value = config[key];
- object.set(key,value);
- }
- }
-
- return object;
- },
- /**
- * Imports a class or a directory.
- *
- * Importing a class is like including the corresponding class file.
- * The main difference is that importing a class is much lighter because it only
- * includes the class file when the class is referenced the first time.
- *
- * Importing a directory is equivalent to adding a directory into the PHP include path.
- * If multiple directories are imported, the directories imported later will take
- * precedence in class file searching (i.e., they are added to the front of the PHP include path).
- *
- * Path aliases are used to import a class or directory. For example,
- * <ul>
- * <li><code>application.components.GoogleMap</code>: import the <code>GoogleMap</code> class.</li>
- * <li><code>application.components.*</code>: import the <code>components</code> directory.</li>
- * </ul>
- *
- * The same path alias can be imported multiple times, but only the first time is effective.
- * Importing a directory does not import any of its subdirectories.
- *
- * Starting from version 1.1.5, this method can also be used to import a class in namespace format
- * (available for PHP 5.3 or above only). It is similar to importing a class in path alias format,
- * except that the dot separator is replaced by the backslash separator. For example, importing
- * <code>application\components\GoogleMap</code> is similar to importing <code>application.components.GoogleMap</code>.
- * The difference is that the former class is using qualified name, while the latter unqualified.
- *
- * Note, importing a class in namespace format requires that the namespace is corresponding to
- * a valid path alias if we replace the backslash characters with dot characters.
- * For example, the namespace <code>application\components</code> must correspond to a valid
- * path alias <code>application.components</code>.
- *
- * @param {String} alias path alias to be imported
- * @param {Boolean} forceInclude whether to include the class file immediately. If false, the class file
- * will be included only when the class is being used. This parameter is used only when
- * the path alias refers to a class.
- * @returns {String} the class name or the directory that this alias refers to
- * @throws {Yii.CException} if the alias is invalid
- */
- imports: function (alias, forceInclude) {
- var result, _imports, pos, namespace, path, classFile, classMap, className, isClass, _includePaths;
- if (forceInclude === undefined) {
- forceInclude = true;
- }
- if(Yii._imports[alias] !== undefined) { // previously imported
-
- return Yii._imports[alias];
- }
-
- if(Yii[alias] !== undefined) {
- return (Yii._imports[alias]=alias);
- }
- if ((pos = alias.indexOf("/")) !== -1) {
- className = String(alias.split("/").pop());
-
- if (className.slice(-3) == ".js") {
-
- className = className.slice(0,-3);
- }
-
- if (Yii[className] !== undefined) {
- return (Yii._imports[alias] = className);
- }
- Yii.include(alias,!forceInclude);
- Yii.classMap[className] = alias;
- Yii._imports[alias] = className;
-
- return className;
- }
- if((pos=alias.indexOf('.'))===-1) { // a simple class name
- result = Yii.autoload(alias, !forceInclude);
- if(forceInclude && !result) {
- throw new Yii.CException(Yii.t('yii','Alias "{alias}" is invalid. Make sure it points to an existing directory or file.',
- {'{alias}':alias}));
- }
- Yii._imports[alias]=alias;
- return alias;
- }
- className=String(alias.split(".").pop());
-
- isClass=className!=='*';
- if (!isClass) {
- throw new Yii.CException("YiiJS does not support importing directories");
- }
- if(Yii[className] !== undefined) {
- return (Yii._imports[alias]=className);
- }
-
- else if((path=Yii.getPathOfAlias(alias))!==false) {
- Yii.include(path + ".js",!forceInclude);
- Yii.classMap[className]=path+'.js';
- return className;
- }
- else {
- throw new Yii.CException(Yii.t('yii','Alias "{alias}" is invalid. Make sure it points to an existing directory or file.',
- {'{alias}':alias}));
- }
- },
- /**
- * Translates an alias into a file path.
- * Note, this method does not ensure the existence of the resulting file path.
- * It only checks if the root alias is valid or not.
- * @param {String} alias alias (e.g. system.web.CController)
- * @returns {Mixed} file path corresponding to the alias, false if the alias is invalid.
- */
- getPathOfAlias: function (alias) {
- var _aliases, pos, rootAlias, _app;
- if(Yii._aliases[alias] !== undefined) {
- return Yii._aliases[alias];
- }
- else if((pos=php.strpos(alias,'.'))!==false) {
- rootAlias=alias.slice(0, pos);
- if(Yii._aliases[rootAlias] !== undefined) {
- return (Yii._aliases[alias]=php.rtrim(Yii._aliases[rootAlias]+'/'+php.str_replace('.','/',alias.slice(pos+1)),'*'+'/'));
- }
- else if(Yii._app !== null && Yii._app instanceof Yii.CWebApplication){
- if(Yii._app.findModule(rootAlias)!==null) {
- return Yii.getPathOfAlias(alias);
- }
- }
- }
- return false;
- },
- /**
- * Create a path alias.
- * Note, this method neither checks the existence of the path nor normalizes the path.
- * @param {String} alias alias to the path
- * @param {String} path the path corresponding to the alias. If this is null, the corresponding
- * path alias will be removed.
- */
- setPathOfAlias: function (alias, path) {
- var _aliases;
- if(php.empty(path)) {
- delete Yii._aliases[alias];
- }
- else {
- Yii._aliases[alias]=php.rtrim(path,'\\/');
- }
- },
- /**
- * Class autoload loader.
- * @param {String} className class name
- * @param {Boolean} async Whether to load this class
- * via an asynchronous AJAX request, otherwise a blocking request is used, defaults to false.
- * @returns {Boolean} whether the class has been loaded successfully
- */
- autoload: function (className, async) {
- var _coreClasses, classMap, namespace, path, result;
- if (async === undefined) {
- async = true;
- }
-
- if(Yii._coreClasses[className] !== undefined) {
- if (Yii[className] !== undefined) {
- return true;
- }
-
- result = Yii.include(YII_PATH+Yii._coreClasses[className], async);
- if (!async) {
- return result;
- }
- }
- else if(Yii.classMap[className] !== undefined) {
- if (Yii[className] !== undefined) {
- return true;
- }
- result = Yii.include(Yii.classMap[className], async);
- if (!async) {
- return result;
- }
- }
- else {
- return Yii[className] !== undefined;
- }
- return true;
- },
-
- /**
- * Includes a remote file, this will be evaled!
- * @param {String} url The URL to load the file from
- * @param {Boolean} async Whether to perform an asynchronous request or not, defaults to true.
- * @param {Function} callback The callback to execute after the included file is evaled
- * @returns {Mixed} either the jQuery ajax request if this is async, or
- * if this is a blocking request returns the content or false depending on whether
- * it succeeded or not.
- */
- include: function (url, async, callback) {
- var options = {}, request;
- if (async === undefined) {
- async = true;
- }
- if (callback === undefined) {
- callback = function () {};
- }
- if(Yii._includePaths[url] !== undefined) { // previously imported
- return Yii._includePaths[url];
- }
- options.url = url;
- options.async = async;
- options.cache = false;
- if (async) {
- options.success = function (res) {
- Yii._includePaths[url] = eval(res);
- callback(Yii._includePaths[url]);
- };
- options.error = function () {
- throw new Yii.CHttpException(404, Yii.t("system", "No such file"));
- };
- return jQuery.ajax(options);
- }
- else {
-
- request = jQuery.ajax(options);
- if (request.status > 399) {
- return false;
- }
- Yii._includePaths[url] = eval(request.responseText);
- callback(Yii._includePaths[url]);
- return Yii._includePaths[url];
-
-
- }
- },
-
-
- /**
- * Writes a trace message.
- * This method will only log a message when the application is in debug mode.
- * @param {String} msg message to be logged
- * @param {String} category category of the message
- * @see log
- */
- trace: function (msg, category) {
- if (category === undefined) {
- category = 'application';
- }
- if(YII_DEBUG) {
- Yii.log(msg,Yii.CLogger.prototype.LEVEL_TRACE,category);
- }
- },
- /**
- * Logs a message.
- * Messages logged by this method may be retrieved via {@link CLogger::getLogs}
- * and may be recorded in different media, such as file, email, database, using
- * {@link CLogRouter}.
- * @param {String} msg message to be logged
- * @param {String} level level of the message (e.g. 'trace', 'warning', 'error'). It is case-insensitive.
- * @param {String} category category of the message (e.g. 'system.web'). It is case-insensitive.
- */
- log: function (msg, level, category) {
- var _logger, traces, count, i, limit, trace, cmd;
- if (level === undefined) {
- level = 'info';
- }
- if (category === undefined) {
- category = 'application';
- }
- if(Yii._logger===null) {
- Yii._logger=new Yii.CLogger();
- }
- if(window['console'] !== undefined && YII_DEBUG && YII_TRACE_LEVEL>0 && level!==Yii.CLogger.prototype.LEVEL_PROFILE) {
- cmd = "log";
- if (level === Yii.CLogger.prototype.LEVEL_ERROR) {
- cmd = "error";
- }
- else if (level === Yii.CLogger.prototype.LEVEL_WARNING) {
- cmd = "warn";
- }
- console[cmd](level + "\t" + php.str_pad(category,30," ") + "\t" + msg);
- }
- Yii._logger.log(msg,level,category);
- },
- /**
- * Marks the begin of a code block for profiling.
- * This has to be matched with a call to {@link endProfile()} with the same token.
- * The begin- and end- calls must also be properly nested, e.g.,
- * <pre>
- * Yii.beginProfile('block1');
- * Yii.beginProfile('block2');
- * Yii.endProfile('block2');
- * Yii.endProfile('block1');
- * </pre>
- * The following sequence is not valid:
- * <pre>
- * Yii.beginProfile('block1');
- * Yii.beginProfile('block2');
- * Yii.endProfile('block1');
- * Yii.endProfile('block2');
- * </pre>
- * @param {String} token token for the code block
- * @param {String} category the category of this log message
- * @see endProfile
- */
- beginProfile: function (token, category) {
- if (category === undefined) {
- category = 'application';
- }
- Yii.log('begin:'+token,Yii.CLogger.prototype.LEVEL_PROFILE,category);
- },
- /**
- * Marks the end of a code block for profiling.
- * This has to be matched with a previous call to {@link beginProfile()} with the same token.
- * @param {String} token token for the code block
- * @param {String} category the category of this log message
- * @see beginProfile
- */
- endProfile: function (token, category) {
- if (category === undefined) {
- category = 'application';
- }
- Yii.log('end:'+token,Yii.CLogger.prototype.LEVEL_PROFILE,category);
- },
- /**
- * @returns {Yii.CLogger} message logger
- */
- getLogger: function () {
- var _logger;
- if(Yii._logger!==null) {
- return Yii._logger;
- }
- else {
- return (Yii._logger=new Yii.CLogger);
- }
- },
- /**
- * Returns a string that can be displayed on your Web page showing Powered-by-Yii information
- * @returns {String} a string that can be displayed on your Web page showing Powered-by-Yii information
- */
- powered: function () {
- return 'Powered by <a href="http://www.yiiframework.com/" rel="external">Yii Framework</a>.';
- },
- /**
- * Translates a message to the specified language.
- * Starting from version 1.0.2, this method supports choice format (see {@link CChoiceFormat}),
- * i.e., the message returned will be chosen from a few candidates according to the given
- * number value. This feature is mainly used to solve plural format issue in case
- * a message has different plural forms in some languages.
- * @param {String} category message category. Please use only word letters. Note, category 'yii' is
- * reserved for Yii framework core code use. See {@link CPhpMessageSource} for
- * more interpretation about message category.
- * @param {String} message the original message
- * @param {Array} params parameters to be applied to the message using <code>strtr</code>.
- * Starting from version 1.0.2, the first parameter can be a number without key.
- * And in this case, the method will call {@link CChoiceFormat::format} to choose
- * an appropriate message translation.
- * Starting from version 1.1.6 you can pass parameter for {@link CChoiceFormat::format}
- * or plural forms format without wrapping it with array.
- * @param {String} source which message source application component to use.
- * Defaults to null, meaning using 'coreMessages' for messages belonging to
- * the 'yii' category and using 'messages' for the rest messages.
- * @param {String} language the target language. If null (default), the {@link CApplication::getLanguage application language} will be used.
- * This parameter has been available since version 1.0.3.
- * @returns {String} the translated message
- * @see CMessageSource
- */
- t: function (category, message, params, source, language) {
- var _app, chunks, expressions, n, i;
- if (params === undefined) {
- params = {};
- }
- if (source === undefined) {
- source = null;
- }
- if (language === undefined) {
- language = null;
- }
-
-
- if(Yii._app!==null) {
- if(source===null) {
- source=(category==='yii'||category==='zii')?'coreMessages':'messages';
- }
- if((source=Yii._app.getComponent(source))!==null && source !== undefined) {
- message=source.translate(category,message,language);
- }
- }
-
- if(params==={} || params === []) {
- return message;
- }
-
- if(params[0] !== undefined) {
- // number choice
- if(php.strpos(message,'|')!==false) {
- if(php.strpos(message,'#')===false) {
- chunks=message.split('|');
- expressions=Yii._app.getLocale(language).getPluralRules();
- n=php.min(php.count(chunks),php.count(expressions));
- if(n) {
- for(i=0;i<n;i++) {
- chunks[i]=expressions[i]+'#'+chunks[i];
- }
- message=chunks.join('|');
- }
- }
- message=Yii.CChoiceFormat.format(message,params[0]);
- }
- if(params['{n}'] === undefined) {
- params['{n}']=params[0];
- }
- delete params[0];
- }
- if (params !== {}) {
- return php.strtr(message,params);
- }
- return message;
- },
- /**
- * Registers a new class autoloader.
- * The new autoloader will be placed before {@link autoload} and after
- * any other existing autoloaders.
- * @param {Function} callback a valid PHP callback (function name or array($className,$methodName)).
- * @since 1.0.10
- */
- registerAutoloader: function (callback) {
-
- },
- /**
- * Removes JSDoc comments from a string
- * TODO: move this somewhere else
- * @param {String} str the string to strip
- * @returns {String} the stripped string
- */
- removeComments: function (str) {
-
- var uid = '_' + (new Date()),
- primatives = [],
- primIndex = 0;
-
- return (
- str
- .replace(/(['"])(\\\1|.)+?\1/g, function(match){
- primatives[primIndex] = match;
- return (uid + '') + primIndex++;
- })
- .replace(/([^\/])(\/(?!\*|\/)(\\\/|.)+?\/[gim]{0,3})/g, function(match, $1, $2){
- primatives[primIndex] = $2;
- return $1 + (uid + '') + primIndex++;
- })
- .replace(/\/\/.*?\/?\*.+?(?=\n|\r|$)|\/\*[\s\S]*?\/\/[\s\S]*?\*\//g, '')
- .replace(/\/\/.+?(?=\n|\r|$)|\/\*[\s\S]+?\*\//g, '')
- .replace(RegExp('\\/\\*[\\s\\S]+' + uid + '\\d+', 'g'), '')
- .replace(RegExp(uid + '(\\d+)', 'g'), function(match, n){
- return primatives[n];
- })
- );
- },
- /**
- * Similar to PHP's preg_match_all
- * @param {RegExp} regex The regular expression to match against
- * @param {String} haystack The string to perform the regex on
- * @returns {Array} an array of matches
- */
- matchAll: function (regex, haystack) {
- var matches = [], i, match;
- match = regex.exec(haystack);
-
- while (match !== null) {
- matches.push(match);
- match = regex.exec(haystack);
- }
- return matches;
- },
- /**
- * Extends a class
- */
- extend: function (childClass, parentClass, properties) {
- childClass.prototype = new Yii[parentClass](false);
- childClass.prototype.constructor = childClass;
- if (properties !== undefined) {
- Yii.forEach(properties, function(name, value) {
- childClass.prototype[name] = value;
- });
- }
- },
-
- /**
- * Implements foreach in JavaScript
- * @param {Mixed} itemList a list of items to iterate through
- * @param {Function} callback The callback function, it will recieve 2 parameters, key and value
- * if the callback returns false, the loop will break.
- */
- forEach: function (itemList, callback) {
- var i, limit;
- if (typeof itemList === "function") {
- return Yii.forEach(itemList(), callback);
- }
- if (Object.prototype.toString.call(itemList) === '[object Array]' || itemList instanceof Yii.CList || itemList instanceof Yii.CStack) {
- limit = itemList.length;
- for (i = 0; i < limit; i++) {
- if (i === "forEach") {
- continue;
- }
- else if (callback(i, itemList[i]) === false) {
- break;
- }
- }
- }
- else {
- for (i in itemList) {
- if (itemList.hasOwnProperty(i)) {
- if (i === "forEach") {
- continue;
- }
- else if (callback(i, itemList[i]) === false) {
- break;
- }
- }
- }
- }
- return itemList;
- },
-
- /**
- * Filter an array of items
- */
- filter: function (items, block) {
- var values = [];
- var thisp = arguments[1];
- for (var i = 0; i < items.length; i++)
- if (block.call(thisp, items[i]))
- values.push(items[i]);
- return values;
- }
- };
- /**
- * A shortcut to application properties.
- * Supports virtual getters and setters, e.g:
- * <pre>
- * $app("securityManager.validationKey") === Yii.app().getSecurityManager().getValidationKey();
- * </pre>
- */
- var $app = function(selector, setVal) {
- var stack, parts, i, limit, item, getter, last;
- if (selector === undefined || php.trim(selector).length === 0) {
- return Yii.app();
- }
- parts = selector.split(".");
-
- limit = parts.length;
- last = limit - 1;
- stack = Yii.app();
- for (i = 0; i < limit; i++) {
-
- if (stack instanceof Yii.CComponent) {
- if (setVal !== undefined) {
- return stack.set(parts.join("."),setVal);
- }
- return stack.get(parts.join("."));
- }
- item = parts.shift();
- if (i === last && setVal !== undefined) {
- if (stack[item] !== undefined) {
- stack[item] = setVal;
- return setVal;
- }
- else if (stack.get !== undefined) {
- stack = stack.set.call(stack, item, setVal);
- return setVal;
- }
- else {
- throw new Yii.CException("No such property: " + item);
- }
- }
- else {
- if (stack[item] !== undefined) {
- stack = stack[item];
- }
- else if (stack.get !== undefined) {
- stack = stack.get.call(stack, item);
- }
- else {
- throw new Yii.CException("No such property: " + item);
- }
- }
- }
-
- return stack;
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CComponent is the base class for all components.
- *
- * CComponent implements the protocol of defining, using properties and events.
- *
- * A property is defined by a getter method, and/or a setter method.
- * Properties can be accessed in the way like accessing normal object members.
- * Reading or writing a property will cause the invocation of the corresponding
- * getter or setter method, e.g
- * <pre>
- * a=component.text; // equivalent to $a=$component->getText();
- * component.text='abc'; // equivalent to $component->setText('abc');
- * </pre>
- * The signatures of getter and setter methods are as follows,
- * <pre>
- * // getter, defines a readable property 'text'
- * public function getText() { +++ }
- * // setter, defines a writable property 'text' with $value to be set to the property
- * public function setText(value) { +++ }
- * </pre>
- *
- * An event is defined by the presence of a method whose name starts with 'on'.
- * The event name is the method name. When an event is raised, functions
- * (called event handlers) attached to the event will be invoked automatically.
- *
- * An event can be raised by calling {@link raiseEvent} method, upon which
- * the attached event handlers will be invoked automatically in the order they
- * are attached to the event. Event handlers must have the following signature,
- * <pre>
- * function eventHandler(event) { +++ }
- * </pre>
- * where $event includes parameters associated with the event.
- *
- * To attach an event handler to an event, see {@link attachEventHandler}.
- * You can also use the following syntax:
- * <pre>
- * component.onClick=callback; // or $component->onClick->add($callback);
- * </pre>
- * where $callback refers to a valid PHP callback. Below we show some callback examples:
- * <pre>
- * 'handleOnClick' // handleOnClick() is a global function
- * [object,'handleOnClick'] // using $object->handleOnClick()
- * ['Page','handleOnClick'] // using Page::handleOnClick()
- * </pre>
- *
- * To raise an event, use {@link raiseEvent}. The on-method defining an event is
- * commonly written like the following:
- * <pre>
- * public function onClick(event)
- * {
- * this.raiseEvent('onClick',event);
- * }
- * </pre>
- * where <code>$event</code> is an instance of {@link CEvent} or its child class.
- * One can then raise the event by calling the on-method instead of {@link raiseEvent} directly.
- *
- * Both property names and event names are case-insensitive.
- *
- * Starting from version 1.0.2, CComponent supports behaviors. A behavior is an
- * instance of {@link IBehavior} which is attached to a component. The methods of
- * the behavior can be invoked as if they belong to the component. Multiple behaviors
- * can be attached to the same component.
- *
- * To attach a behavior to a component, call {@link attachBehavior}; and to detach the behavior
- * from the component, call {@link detachBehavior}.
- *
- * A behavior can be temporarily enabled or disabled by calling {@link enableBehavior}
- * or {@link disableBehavior}, respectively. When disabled, the behavior methods cannot
- * be invoked via the component.
- *
- * Starting from version 1.1.0, a behavior's properties (either its public member variables or
- * its properties defined via getters and/or setters) can be accessed through the component it
- * is attached to.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CComponent.php 3066 2011-03-13 14:22:55Z qiang.xue $
- * @package system.base
- * @since 1.0
- * @author Charles Pick
- * @class
- */
- Yii.CComponent = function CComponent() {
- };
- Yii.CComponent.prototype._e = null;
- Yii.CComponent.prototype._m = null;
- /**
- * Gets the class name for this item.
- * Since JavaScript doesn't really support this we
- * abuse function declarations to implement it,
- * for example instead of:
- * <pre>
- * Yii.Blah = function() { ... }
- * </pre>
- * we use:
- * <pre>
- * Yii.Blah = function Blah() { ... }
- * </pre>
- * We can now retrieve the name of the class by inspecting the constructor.
- */
- Yii.CComponent.prototype.getClassName = function() {
- var matches, className;
-
- matches = /function(.*)\((.*)\)/.exec((this).constructor);
- if (matches) {
- return php.trim(matches[1]);
- }
- };
- /**
- * Returns a property value, an event handler list or a behavior based on its name.
- * Do not call this method. This is a PHP magic method that we override
- * to allow using the following syntax to read a property or obtain event handlers:
- * <pre>
- * value=component.propertyName;
- * handlers=component.eventName;
- * </pre>
- * @param {String} name the property name or event name
- * @returns {Mixed} the property value, event handlers attached to the event, or the named behavior (since version 1.0.2)
- * @throws {Yii.CException} if the property or event is not defined
- * @see __set
- */
- Yii.CComponent.prototype.get = function (name) {
- var getter, i, object, nameParts = [], limit;
-
- if (name.indexOf !== undefined && name.indexOf(".") !== -1) {
- nameParts = name.split(".");
- name = nameParts.shift();
- }
- if (this[name] !== undefined) {
- object = this[name];
- if (nameParts.length > 0) {
- if (object instanceof Yii.CComponent) {
- return object.get(nameParts.join("."));
- }
- limit = nameParts.length;
- for (i = 0; i < limit; i++) {
- name = nameParts.shift();
- object = object[name];
- if (nameParts.length === 0) {
- return object;
- }
-
- if (object instanceof Yii.CComponent) {
- return object.get(nameParts.join("."));
- }
- }
- }
- return object;
- }
- getter='get'+php.ucfirst(name);
- if(php.method_exists(this,getter)) {
- object = this[getter]();
- if (nameParts.length > 0) {
- if (object instanceof Yii.CComponent) {
- return object.get(nameParts.join("."));
- }
- limit = nameParts.length;
- for (i = 0; i < limit; i++) {
- name = nameParts.shift();
- object = object[name];
- if (nameParts.length === 0) {
- return object;
- }
-
- if (object instanceof Yii.CComponent) {
- return object.get(nameParts.join("."));
- }
-
- }
- }
- return object;
- }
- else if(php.strncasecmp(name,'on',2)===0 && php.method_exists(this,name)) {
- // duplicating getEventHandlers() here for performance
- name=name.toLowerCase();
- if(this._e[name] === undefined) {
- this._e[name]=new Yii.CList();
- }
- return this._e[name];
- }
- else if(this._m !== null && this._m[name] !== undefined) {
- return this._m[name];
- }
- else if(this._m !== null) {
- for (i in this._m) {
- if (this._m.hasOwnProperty(i)) {
-
- object = this._m[i];
- try {
- if(object.getEnabled() && (php.property_exists(object,name) || object.canGetProperty(name))) {
- if (nameParts.length > 0) {
- return object.get(nameParts.join("."));
- }
- return object.get(name);
- }
- }
- catch (e) {
- console.log(e);
- }
- }
- }
- }
- console.log(this.getClassName() + " : " + name);
- throw new Yii.CException(Yii.t('yii','Property "{class}.{property}" is not defined.',
- {'{class}':this.getClassName(), '{property}':name}));
- };
- /**
- * Sets value of a component property.
- * Do not call this method. This is a PHP magic method that we override
- * to allow using the following syntax to set a property or attach an event handler
- * <pre>
- * this.propertyName=value;
- * this.eventName=callback;
- * </pre>
- * @param {String} name the property name or the event name
- * @param {Mixed} value the property value or callback
- * @throws {Yii.CException} if the property/event is not defined or the property is read only.
- * @see __get
- */
- Yii.CComponent.prototype.set = function (name, value) {
- var setter, i, object, nameParts = [];
- if (name.indexOf(".") !== -1) {
- nameParts = name.split(".");
- name = nameParts.pop();
- return (this.get(nameParts.join("."))[name] = value);
- }
- if (this[name] !== undefined) {
- return (this[name] = value);
- }
-
- setter='set'+php.ucfirst(name);
- if(php.method_exists(this,setter)) {
- return this[setter](value);
- }
- else if(php.strncasecmp(name,'on',2)===0 && php.method_exists(this,name)) {
- // duplicating getEventHandlers() here for performance
- name=name.toLowerCase();
- if(this._e[name] === undefined) {
- this._e[name]=new Yii.CList();
- }
- return this._e[name].add(value);
- }
- else if(this._m !== null) {
- for (i in this._m) {
- if (this._m.hasOwnProperty(i)) {
-
- object = this._m[i];
-
- if(object.getEnabled() && (php.property_exists(object,name) || object.canSetProperty(name))) {
- return (object.set(name,value));
- }
- }
- }
- }
- if(php.method_exists(this,'get'+php.ucfirst(name))) {
- throw new Yii.CException(Yii.t('yii','Property "{class}.{property}" is read only.',
- {'{class}':this.getClassName(), '{property}':name}));
- }
- else {
- throw new Yii.CException(Yii.t('yii','Property "{class}.{property}" is not defined.',
- {'{class}':this.getClassName(), '{property}':name}));
- }
- };
- /**
- * Checks if a property value is null.
- * Do not call this method. This is a PHP magic method that we override
- * to allow using isset() to detect if a component property is set or not.
- * @param {String} name the property name or the event name
- * @since 1.0.1
- */
- Yii.CComponent.prototype.isset = function (name) {
- var getter, i, object, nameParts = [], value;
- if (name.indexOf(".") !== -1) {
- nameParts = name.split(".");
- name = nameParts.pop();
- try {
- value = this.get(nameParts.join("."))[name];
- if (value !== undefined && value !== null) {
- return true;
- }
- return false;
- }
- catch (e) {
- return false;
- }
- }
- if (this[name] !== undefined) {
- return true;
- }
- getter='get'+php.ucfirst(name);
- if(php.method_exists(this,getter)) {
- return (this[getter]()!==null);
- }
- else if(php.strncasecmp(name,'on',2)===0 && php.method_exists(this,name))
- {
- name=name.toLowerCase();
- return this._e !== null && this._e[name] !== undefined && this._e[name].getCount();
- }
- else if(this._m !== null) {
- if(this._m[name] !== undefined) {
- return true;
- }
- for (i in this._m) {
- if (this._m.hasOwnProperty(i)) {
- object = this._m[i];
- if(object.getEnabled() && (php.property_exists(object,name) || object.canGetProperty(name))) {
- return true;
- }
- }
- }
- }
- return false;
- };
- /**
- * Sets a component property to be null.
- * Do not call this method. This is a PHP magic method that we override
- * to allow using unset() to set a component property to be null.
- * @param {String} name the property name or the event name
- * @throws {Yii.CException} if the property is read only.
- * @since 1.0.1
- */
- Yii.CComponent.prototype.unset = function (name) {
- var setter, i, object, nameParts = [];
- if (name.indexOf(".") !== -1) {
- nameParts = name.split(".");
- name = nameParts.pop();
- object = this.get(nameParts.join("."))[name];
- if (object.unset !== undefined) {
- return object.unset(name);
- }
- return (this.get(nameParts.join("."))[name] = null);
- }
- setter='set'+php.ucfirst(name);
- if (this[name] !== undefined) {
- this[name] = null;
- return;
- }
- else if(php.method_exists(this,setter)) {
- this[setter](null);
- }
- else if(php.strncasecmp(name,'on',2)===0 && php.method_exists(this,name)) {
- delete this._e[name.toLowerCase()];
- }
- else if(this._m !== null)
- {
- if(this._m[name] !== undefined) {
- this.detachBehavior(name);
- }
- else
- {
- for (i in this._m) {
- if (this._m.hasOwnProperty(i)) {
- object = this._m[i];
- if(object.getEnabled()) {
- if(php.property_exists(object,name)) {
- return (object[name]=null);
- }
- else if(object.canSetProperty(name)) {
- return object[setter](null);
- }
- }
- }
- }
- }
- }
- else if(php.method_exists(this,'get'+name)) {
- throw new Yii.CException(Yii.t('yii','Property "{class}.{property}" is read only.',
- {'{class}':this.getClassName(), '{property}':name}));
- }
- };
- /**
- * Calls the named method which is not a class method.
- * Do not call this method. This is a PHP magic method that we override
- * to implement the behavior feature.
- * @param {String} name the method name
- * @param {Array} parameters method parameters
- * @returns {Mixed} the method return value
- * @since 1.0.2
- */
- Yii.CComponent.prototype.call = function (name, parameters) {
- var i, object;
- if (this[name] !== undefined) {
- return php.call_user_func_array([this,name],parameters);
- }
- else if(this._m!==null) {
- for (i in this._m) {
- if (this._m.hasOwnProperty(i)) {
- object = this._m[i];
- if(object.getEnabled() && php.method_exists(object,name)) {
- return php.call_user_func_array([object,name],parameters);
- }
- }
- }
- }
-
- throw new Yii.CException(Yii.t('yii','{class} does not have a method named "{name}".',
- {'{class}':this.getClassName(), '{name}':name}));
- };
- /**
- * Returns the named behavior object.
- * The name 'asa' stands for 'as a'.
- * @param {String} behavior the behavior name
- * @returns {IBehavior} the behavior object, or null if the behavior does not exist
- * @since 1.0.2
- */
- Yii.CComponent.prototype.asa = function (behavior) {
- return this._m !== null && this._m[behavior] !== undefined ? this._m[behavior] : null;
- };
- /**
- * Attaches a list of behaviors to the component.
- * Each behavior is indexed by its name and should be an instance of
- * {@link IBehavior}, a string specifying the behavior class, or an
- * array of the following structure:
- * <pre>
- * {
- * 'class':'path.to.BehaviorClass',
- * 'property1':'value1',
- * 'property2':'value2',
- * }
- * </pre>
- * @param {Array} behaviors list of behaviors to be attached to the component
- * @since 1.0.2
- */
- Yii.CComponent.prototype.attachBehaviors = function (behaviors) {
- var name, behavior;
- for (name in behaviors) {
- if (behaviors.hasOwnProperty(name)) {
- behavior = behaviors[name];
- this.attachBehavior(name,behavior);
- }
- }
- };
- /**
- * Detaches all behaviors from the component.
- * @since 1.0.2
- */
- Yii.CComponent.prototype.detachBehaviors = function () {
- var name, behavior;
- if(this._m!==null) {
- for (name in this._m) {
- if (this._m.hasOwnProperty(name)) {
- behavior = this._m[name];
- this.detachBehavior(name);
- }
- }
- this._m=null;
- }
- };
- /**
- * Attaches a behavior to this component.
- * This method will create the behavior object based on the given
- * configuration. After that, the behavior object will be initialized
- * by calling its {@link IBehavior::attach} method.
- * @param {String} name the behavior's name. It should uniquely identify this behavior.
- * @param {Mixed} behavior the behavior configuration. This is passed as the first
- * parameter to {@link YiiBase::createComponent} to create the behavior object.
- * @returns {IBehavior} the behavior object
- * @since 1.0.2
- */
- Yii.CComponent.prototype.attachBehavior = function (name, behavior) {
- if(!(behavior instanceof Yii.CBehavior)) {
- behavior=Yii.createComponent(behavior);
- }
- behavior.setEnabled(true);
- behavior.attach(this);
- if (this._m === null) {
- this._m = {};
- }
- return (this._m[name]=behavior);
- };
- /**
- * Detaches a behavior from the component.
- * The behavior's {@link IBehavior::detach} method will be invoked.
- * @param {String} name the behavior's name. It uniquely identifies the behavior.
- * @returns {IBehavior} the detached behavior. Null if the behavior does not exist.
- * @since 1.0.2
- */
- Yii.CComponent.prototype.detachBehavior = function (name) {
- var behavior;
- if(this._m[name] !== undefined) {
- this._m[name].detach(this);
- behavior=this._m[name];
- delete this._m[name];
- return behavior;
- }
- };
- /**
- * Enables all behaviors attached to this component.
- * @since 1.0.2
- */
- Yii.CComponent.prototype.enableBehaviors = function () {
- var i, behavior;
- if(this._m!==null) {
- for (i in this._m) {
- if (this._m.hasOwnProperty(i)) {
- behavior = this._m[i];
- behavior.setEnabled(true);
- }
- }
- }
- };
- /**
- * Disables all behaviors attached to this component.
- * @since 1.0.2
- */
- Yii.CComponent.prototype.disableBehaviors = function () {
- var i, behavior;
- if(this._m!==null) {
- for (i in this._m) {
- if (this._m.hasOwnProperty(i)) {
- behavior = this._m[i];
- behavior.setEnabled(false);
- }
- }
- }
- };
- /**
- * Enables an attached behavior.
- * A behavior is only effective when it is enabled.
- * A behavior is enabled when first attached.
- * @param {String} name the behavior's name. It uniquely identifies the behavior.
- * @since 1.0.2
- */
- Yii.CComponent.prototype.enableBehavior = function (name) {
- if(this._m !== null && this._m[name] !== undefined) {
- this._m[name].setEnabled(true);
- }
- };
- /**
- * Disables an attached behavior.
- * A behavior is only effective when it is enabled.
- * @param {String} name the behavior's name. It uniquely identifies the behavior.
- * @since 1.0.2
- */
- Yii.CComponent.prototype.disableBehavior = function (name) {
- if(this._m !== null && this._m[name] !== undefined) {
- this._m[name].setEnabled(false);
- }
- };
- /**
- * Determines whether a property is defined.
- * A property is defined if there is a getter or setter method
- * defined in the class. Note, property names are case-insensitive.
- * @param {String} name the property name
- * @returns {Boolean} whether the property is defined
- * @see canGetProperty
- * @see canSetProperty
- */
- Yii.CComponent.prototype.hasProperty = function (name) {
- return this[name] !== undefined || php.method_exists(this,'get'+php.ucfirst(name)) || php.method_exists(this,'set'+php.ucfirst(name));
- };
- /**
- * Determines whether a property can be read.
- * A property can be read if the class has a getter method
- * for the property name. Note, property name is case-insensitive.
- * @param {String} name the property name
- * @returns {Boolean} whether the property can be read
- * @see canSetProperty
- */
- Yii.CComponent.prototype.canGetProperty = function (name) {
- return this[name] !== undefined || php.method_exists(this,'get'+php.ucfirst(name));
- };
- /**
- * Determines whether a property can be set.
- * A property can be written if the class has a setter method
- * for the property name. Note, property name is case-insensitive.
- * @param {String} name the property name
- * @returns {Boolean} whether the property can be written
- * @see canGetProperty
- */
- Yii.CComponent.prototype.canSetProperty = function (name) {
- return this[name] !== undefined || php.method_exists(this,'set'+php.ucfirst(name));
- };
- /**
- * Determines whether an event is defined.
- * An event is defined if the class has a method named like 'onXXX'.
- * Note, event name is case-insensitive.
- * @param {String} name the event name
- * @returns {Boolean} whether an event is defined
- */
- Yii.CComponent.prototype.hasEvent = function (name) {
- return !php.strncasecmp(name,'on',2) && php.method_exists(this,name);
- };
- /**
- * Checks whether the named event has attached handlers.
- * @param {String} name the event name
- * @returns {Boolean} whether an event has been attached one or several handlers
- */
- Yii.CComponent.prototype.hasEventHandler = function (name) {
-
- return this._e !== null && this._e[name] !== undefined && this._e[name].getCount()>0;
- };
- /**
- * Returns the list of attached event handlers for an event.
- * @param {String} name the event name
- * @returns {Yii.CList} list of attached event handlers for the event
- * @throws {Yii.CException} if the event is not defined
- */
- Yii.CComponent.prototype.getEventHandlers = function (name) {
- if(this.hasEvent(name)) {
-
- if (this._e === null) {
- this._e = {};
- }
- if(this._e[name] === undefined) {
- this._e[name]=new Yii.CList();
- }
- return this._e[name];
- }
- else {
- throw new Yii.CException(Yii.t('yii','Event "{class}.{event}" is not defined.',
- {'{class}':this.getClassName(), '{event}':name}));
- }
- };
- /**
- * Attaches an event handler to an event.
- *
- * An event handler must be a valid PHP callback, i.e., a string referring to
- * a global function name, or an array containing two elements with
- * the first element being an object and the second element a method name
- * of the object.
- *
- * An event handler must be defined with the following signature,
- * <pre>
- * function handlerName(event) {}
- * </pre>
- * where $event includes parameters associated with the event.
- *
- * This is a convenient method of attaching a handler to an event.
- * It is equivalent to the following code:
- * <pre>
- * component.getEventHandlers(eventName).add(eventHandler);
- * </pre>
- *
- * Using {@link getEventHandlers}, one can also specify the excution order
- * of multiple handlers attaching to the same event. For example:
- * <pre>
- * component.getEventHandlers(eventName).insertAt(0,eventHandler);
- * </pre>
- * makes the handler to be invoked first.
- *
- * @param {String} name the event name
- * @param {Yii.Callback} handler the event handler
- * @throws {Yii.CException} if the event is not defined
- * @see detachEventHandler
- */
- Yii.CComponent.prototype.attachEventHandler = function (name, handler) {
- this.getEventHandlers(name).add(handler);
- };
- /**
- * Detaches an existing event handler.
- * This method is the opposite of {@link attachEventHandler}.
- * @param {String} name event name
- * @param {Yii.Callback} handler the event handler to be removed
- * @returns {Boolean} if the detachment process is successful
- * @see attachEventHandler
- */
- Yii.CComponent.prototype.detachEventHandler = function (name, handler) {
- if(this.hasEventHandler(name)) {
- return this.getEventHandlers(name).remove(handler)!==false;
- }
- else {
- return false;
- }
- };
- /**
- * Raises an event.
- * This method represents the happening of an event. It invokes
- * all attached handlers for the event.
- * @param {String} name the event name
- * @param {Yii.CEvent} event the event parameter
- * @throws {Yii.CException} if the event is undefined or an event handler is invalid.
- */
- Yii.CComponent.prototype.raiseEvent = function (name, event) {
- var i, handler, object, method, limit;
- if(this._e !== null && this._e[name] !== undefined) {
- limit = this._e[name].length;
- for (i = 0; i < limit; i++) {
- handler = this._e[name][i];
- if(typeof(handler) === 'string') {
- php.call_user_func(handler,event);
- }
- if(Object.prototype.toString.call(handler) === '[object Array]') {
- // an array: 0 - object, 1 - method name
- object = handler[0];
- method = handler[1];
-
- if(typeof(object) === 'string') { // static method call
- php.call_user_func(handler,event);
- }
- else if(php.method_exists(object,method)) {
-
- object[method](event);
- }
- else {
- throw new Yii.CException(Yii.t('yii','Event "{class}.{event}" is attached with an invalid handler "{handler}".',
- {'{class}':this.getClassName(), '{event}':name, '{handler}':handler[1]}));
- }
- }
- else if (typeof handler === "function") { // callback function
- php.call_user_func(handler,event);
- }
- else {
- console.log(i);
- console.log(name);
- console.log(handler);
- throw new Yii.CException(Yii.t('yii','Event "{class}.{event}" is attached with an invalid handler "{handler}".',
- {'{class}':this.getClassName(), '{event}':name, '{handler}':handler}));
- }
- // stop further handling if param.handled is set true
- if((event instanceof Yii.CEvent) && event.handled) {
- return;
- }
-
- }
- }
- else if(YII_DEBUG && !this.hasEvent(name)) {
- throw new Yii.CException(Yii.t('yii','Event "{class}.{event}" is not defined.',
- {'{class}':this.getClassName(), '{event}':name}));
- }
- };
- /**
- * Evaluates a PHP expression or callback under the context of this component.
- *
- * Valid PHP callback can be class method name in the form of
- * array(ClassName/Object, MethodName), or anonymous function (only available in PHP 5.3.0 or above).
- *
- * If a PHP callback is used, the corresponding function/method signature should be
- * <pre>
- * function foo(param1, param2, +++, component) { +++ }
- * </pre>
- * where the array elements in the second parameter to this method will be passed
- * to the callback as $param1, $param2, ...; and the last parameter will be the component itself.
- *
- * If a PHP expression is used, the second parameter will be "extracted" into PHP variables
- * that can be directly accessed in the expression. See {@link http://us.php.net/manual/en/function.extract.php PHP extract}
- * for more details. In the expression, the component object can be accessed using $this.
- *
- * @param {Mixed} _expression_ a PHP expression or PHP callback to be evaluated.
- * @param {Array} _data_ additional parameters to be passed to the above expression/callback.
- * @returns {Mixed} the expression result
- * @since 1.1.0
- */
- Yii.CComponent.prototype.evaluateExpression = function (_expression_, _data_) {
- if (_data_ === undefined) {
- _data_ = [];
- }
- if(typeof(_expression_) === 'string')
- {
- php.extract(_data_);
- return eval('return '+_expression_+';');
- }
- else
- {
- _data_.push(this);
- return php.call_user_func_array(_expression_, _data_);
- }
- }/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CApplicationComponent is the base class for application component classes.
- *
- * CApplicationComponent implements the basic methods required by {@link IApplicationComponent}.
- *
- * When developing an application component, try to put application component initialization code in
- * the {@link init()} method instead of the constructor. This has the advantage that
- * the application component can be customized through application configuration.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CApplicationComponent.php 2799 2011-01-01 19:31:13Z qiang.xue $
- * @package system.base
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CComponent
- */
- Yii.CApplicationComponent = function CApplicationComponent() {
- };
- Yii.CApplicationComponent.prototype = new Yii.CComponent();
- Yii.CApplicationComponent.prototype.constructor = Yii.CApplicationComponent;
- /**
- * @var {Array} the behaviors that should be attached to this component.
- * The behaviors will be attached to the component when {@link init} is called.
- * Please refer to {@link CModel::behaviors} on how to specify the value of this property.
- * @since 1.0.2
- */
- Yii.CApplicationComponent.prototype.behaviors = [];
- Yii.CApplicationComponent.prototype._initialized = false;
- /**
- * Initializes the application component.
- * This method is required by {@link IApplicationComponent} and is invoked by application.
- * If you override this method, make sure to call the parent implementation
- * so that the application component can be marked as initialized.
- */
- Yii.CApplicationComponent.prototype.init = function () {
- this.attachBehaviors(this.behaviors);
- this._initialized=true;
- };
- /**
- * Checks if this application component bas been initialized.
- * @returns {Boolean} whether this application component has been initialized (ie, {@link init()} is invoked).
- */
- Yii.CApplicationComponent.prototype.getIsInitialized = function () {
- return this._initialized;
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CException represents a generic exception for all purposes.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CException.php 2799 2011-01-01 19:31:13Z qiang.xue $
- * @package system.base
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.Exception
- */
- Yii.CException = function CException (message) {
- if (message === false) {
- return;
- }
- this.message = message;
-
- };
- Yii.CException.prototype = new Error();
- Yii.CException.prototype.constructor = Yii.CException;
- /**
- * Gets a basic stack trace
- * @returns {Array} An array of function calls
- */
- Yii.CException.prototype.stacktrace = function () {
- function st2(f) {
- return !f ? [] :
- st2(f.caller).concat([f.toString().split('(')[0].substring(9) + '(' + Array.prototype.slice.call(f.arguments).join(',') + ')']);
- }
- return st2(arguments.callee.caller);
- };
- /**
- * Gets the stack trace as a string
- * @returns {String} the stack trace, latest item first
- */
- Yii.CException.prototype.getTraceAsString = function () {
- return this.stacktrace().reverse().join("\n");
- };
- /**
- * Gets the exception message
- * @returns {String} the message associated with this error
- */
- Yii.CException.prototype.getMessage = function () {
- return this.message;
- }
- /*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CEvent is the base class for all event classes.
- *
- * It encapsulates the parameters associated with an event.
- * The {@link sender} property describes who raises the event.
- * And the {@link handled} property indicates if the event is handled.
- * If an event handler sets {@link handled} to true, those handlers
- * that are not invoked yet will not be invoked anymore.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CComponent.php 3066 2011-03-13 14:22:55Z qiang.xue $
- * @package system.base
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CComponent
- */
- Yii.CEvent = function CEvent(sender, params) {
- if (sender !== false) {
- this.construct(sender, params);
- }
- };
- Yii.CEvent.prototype = new Yii.CComponent();
- Yii.CEvent.prototype.constructor = Yii.CEvent;
- /**
- * @var {Object} the sender of this event
- */
- Yii.CEvent.prototype.sender = null;
- /**
- * @var {Boolean} whether the event is handled. Defaults to false.
- * When a handler sets this true, the rest of the uninvoked event handlers will not be invoked anymore.
- */
- Yii.CEvent.prototype.handled = false;
- /**
- * @var {Mixed} additional event parameters.
- * @since 1.1.7
- */
- Yii.CEvent.prototype.params = null;
- /**
- * Constructor.
- * @param {Mixed} sender sender of the event
- * @param {Mixed} params additional parameters for the event
- */
- Yii.CEvent.prototype.construct = function (sender, params) {
- if (sender === undefined) {
- sender = null;
- }
- if (params === undefined) {
- params = null;
- }
- this.sender=sender;
- this.params=params;
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CEnumerable is the base class for all enumerable types.
- *
- * To define an enumerable type, extend CEnumberable and define string constants.
- * Each constant represents an enumerable value.
- * The constant name must be the same as the constant value.
- * For example,
- * <pre>
- * class TextAlign extends Yii.CEnumerable
- * {
- * const Left='Left';
- * const Right='Right';
- * }
- * </pre>
- * Then, one can use the enumerable values such as TextAlign::Left and
- * TextAlign::Right.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CComponent.php 3066 2011-03-13 14:22:55Z qiang.xue $
- * @package system.base
- * @since 1.0
- * @author Charles Pick
- * @class
- */
- Yii.CEnumerable = function CEnumerable () {
- };
- /*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CModule is the base class for module and application classes.
- *
- * CModule mainly manages application components and sub-modules.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CModule.php 3001 2011-02-24 16:42:44Z alexander.makarow $
- * @package system.base
- * @since 1.0.4
- * @author Charles Pick
- * @class
- * @extends Yii.CComponent
- */
- Yii.CModule = function CModule (id, parent, config) {
- if (id !== false) {
- this.models = {};
- this.views = {};
- this.controllers = {};
-
- this.construct(id, parent, config);
- }
- };
- Yii.CModule.prototype = new Yii.CComponent();
- Yii.CModule.prototype.constructor = Yii.CModule;
- /**
- * @var {Array} the IDs of the application components that should be preloaded.
- */
- Yii.CModule.prototype.preload = [];
- /**
- * @var {Array} the behaviors that should be attached to the module.
- * The behaviors will be attached to the module when {@link init} is called.
- * Please refer to {@link CModel::behaviors} on how to specify the value of this property.
- */
- Yii.CModule.prototype.behaviors = {};
- Yii.CModule.prototype._id = null;
- Yii.CModule.prototype._parentModule = null;
- Yii.CModule.prototype._basePath = null;
- Yii.CModule.prototype._modulePath = null;
- Yii.CModule.prototype._params = null;
- Yii.CModule.prototype._modules = {};
- Yii.CModule.prototype._moduleConfig = {};
- Yii.CModule.prototype._components = {};
- Yii.CModule.prototype._componentConfig = {};
- /**
- * jQuery events to delegate for this module.
- * Array should be of the following format:
- * <pre>
- * [
- * ['#selector a.someLink', 'click', function (e) { alert("clicked!")}],
- * ['#selector form', 'submit', function (e) { alert('Submitted!'); e.preventDefault(); }]
- * ]
- * </pre>
- * These events will be bound to their selectors when the module is run
- * @var Array
- */
- Yii.CModule.prototype.delegates = [];
- /**
- * Holds a list of models belonging to this module
- */
- Yii.CModule.prototype.models = {};
- /**
- * Holds a list of views belonging to this module
- */
- Yii.CModule.prototype.views = {};
- /**
- * Holds a list of controllers belonging to this module
- */
- Yii.CModule.prototype.controllers = {};
- /**
- * Constructor.
- * @param {String} id the ID of this module
- * @param {Yii.CModule} parent the parent module (if any)
- * @param {Mixed} config the module configuration. It can be either an array or
- * the path of a PHP file returning the configuration array.
- */
- Yii.CModule.prototype.construct = function (id, parent, config) {
- if (config === undefined) {
- config = {};
- }
- this._id=id;
- this._parentModule=parent;
- // set basePath at early as possible to avoid trouble
-
- if(config.basePath !== undefined) {
- this.setBasePath(config.basePath);
- delete config.basePath;
- }
- Yii.setPathOfAlias(id,this.getBasePath());
- this.preinit();
- this.configure(config);
- this.attachBehaviors(this.behaviors);
- this.preloadComponents();
- this.init();
- };
- /**
- * Getter magic method.
- * This method is overridden to support accessing application components
- * like reading module properties.
- * @param {String} name application component or property name
- * @returns {Mixed} the named property value
- */
- Yii.CModule.prototype.get = function (name) {
- if(this.hasComponent(name)) {
- return this.getComponent(name);
- }
- else {
- return Yii.CComponent.prototype.get.call(this, name);
- }
- };
- /**
- * Checks if a property value is null.
- * This method overrides the parent implementation by checking
- * if the named application component is loaded.
- * @param {String} name the property name or the event name
- * @returns {Boolean} whether the property value is null
- */
- Yii.CModule.prototype.isset = function (name) {
- if(this.hasComponent(name)) {
- return this.getComponent(name)!==null;
- }
- else {
- return Yii.CComponent.prototype.isset.call(this, name);
- }
- };
- /**
- * Returns the module ID.
- * @returns {String} the module ID.
- */
- Yii.CModule.prototype.getId = function () {
- return this._id;
- };
- /**
- * Sets the module ID.
- * @param {String} id the module ID
- */
- Yii.CModule.prototype.setId = function (id) {
- this._id=id;
- };
- /**
- * Returns the root directory of the module.
- * @returns {String} the root directory of the module. Defaults to the directory containing the module class.
- */
- Yii.CModule.prototype.getBasePath = function () {
- var classVar;
- if(this._basePath===null) {
- classVar=new ReflectionClass(php.get_class(this));
- this._basePath=php.dirname(classVar.getFileName());
- }
- return this._basePath;
- };
- /**
- * Sets the root directory of the module.
- * This method can only be invoked at the beginning of the constructor.
- * @param {String} path the root directory of the module.
- */
- Yii.CModule.prototype.setBasePath = function (path) {
- this._basePath=path;
- };
- /**
- * Returns user-defined parameters.
- * @returns {Yii.CAttributeCollection} the list of user-defined parameters
- */
- Yii.CModule.prototype.getParams = function () {
- if(this._params!==null) {
- return this._params;
- }
- else
- {
- this._params=new Yii.CAttributeCollection();
- this._params.caseSensitive=true;
- return this._params;
- }
- };
- /**
- * Sets user-defined parameters.
- * @param {Array} value user-defined parameters. This should be in name-value pairs.
- */
- Yii.CModule.prototype.setParams = function (value) {
- var params, k, v;
- params=this.getParams();
- for (k in value) {
- if (value.hasOwnProperty(k)) {
- v = value[k];
- params.add(k,v);
- }
- }
- };
- /**
- * Returns the directory that contains the application modules.
- * @returns {String} the directory that contains the application modules. Defaults to the 'modules' subdirectory of {@link basePath}.
- */
- Yii.CModule.prototype.getModulePath = function () {
- if(this._modulePath!==null) {
- return this._modulePath;
- }
- else {
- return (this._modulePath=this.getBasePath()+"/"+'modules');
- }
- };
- /**
- * Sets the directory that contains the application modules.
- * @param {String} value the directory that contains the application modules.
- */
- Yii.CModule.prototype.setModulePath = function (value) {
- this._modulePath = value;
-
- };
- /**
- * Sets the aliases that are used in the module.
- * @param {Array} aliases list of aliases to be imported
- */
- Yii.CModule.prototype.setImport = function (aliases) {
- var i, alias;
- for (i in aliases) {
- if (aliases.hasOwnProperty(i)) {
- alias = aliases[i];
- Yii.imports(alias);
- }
- }
- };
- /**
- * Defines the root aliases.
- * @param {Array} mappings list of aliases to be defined. The array keys are root aliases,
- * while the array values are paths or aliases corresponding to the root aliases.
- * For example,
- * <pre>
- * {
- * 'models':'application.models', // an existing alias
- * 'extensions':'application.extensions', // an existing alias
- * 'backend':php.dirname(__FILE__)+'/../backend', // a directory
- * }
- * </pre>
- * @since 1.0.5
- */
- Yii.CModule.prototype.setAliases = function (mappings) {
- var path, alias, name;
- for (name in mappings) {
- if (mappings.hasOwnProperty(name)) {
- alias = mappings[name];
- if((path=Yii.getPathOfAlias(alias))!==false) {
- Yii.setPathOfAlias(name,path);
- }
- else {
- Yii.setPathOfAlias(name,alias);
- }
- }
- }
- };
- /**
- * Returns the parent module.
- * @returns {Yii.CModule} the parent module. Null if this module does not have a parent.
- */
- Yii.CModule.prototype.getParentModule = function () {
- return this._parentModule;
- };
- /**
- * Retrieves the named application module.
- * The module has to be declared in {@link modules}. A new instance will be created
- * when calling this method with the given ID for the first time.
- * @param {String} id application module ID (case-sensitive)
- * @returns {Yii.CModule} the module instance, null if the module is disabled or does not exist.
- */
- Yii.CModule.prototype.getModule = function (id) {
- var config, classVar, module;
- if(this._modules[id] !== undefined) {
- return this._modules[id];
- }
- else if(this._moduleConfig[id] !== undefined) {
- config=this._moduleConfig[id];
- if(config.enabled === undefined || config.enabled) {
- Yii.trace("Loading \"" + id + "\" module",'system.base.CModule');
- classVar=config['class'];
- delete config['class'];
- if(this===Yii.app()) {
- module=Yii.createComponent(classVar,id,null,config);
- }
- else {
- module=Yii.createComponent(classVar,this.getId()+'/'+id,this,config);
- }
- return (this._modules[id]=module);
- }
- }
- };
- /**
- * Returns a value indicating whether the specified module is installed.
- * @param {String} id the module ID
- * @returns {Boolean} whether the specified module is installed.
- * @since 1.1.2
- */
- Yii.CModule.prototype.hasModule = function (id) {
- return this._moduleConfig[id] !== undefined || this._modules[id] !== undefined;
- };
- /**
- * Returns the configuration of the currently installed modules.
- * @returns {Array} the configuration of the currently installed modules (module ID => configuration)
- */
- Yii.CModule.prototype.getModules = function () {
- return this._moduleConfig;
- };
- /**
- * Configures the sub-modules of this module.
- *
- * Call this method to declare sub-modules and configure them with their initial property values.
- * The parameter should be an array of module configurations. Each array element represents a single module,
- * which can be either a string representing the module ID or an ID-configuration pair representing
- * a module with the specified ID and the initial property values.
- *
- * For example, the following array declares two modules:
- * <pre>
- * {
- * 'admin', // a single module ID
- * 'payment':{ // ID-configuration pair
- * 'server':'paymentserver.com',
- * },
- * }
- * </pre>
- *
- * By default, the module class is determined using the expression <code>ucfirst($moduleID).'Module'</code>.
- * And the class file is located under <code>modules/$moduleID</code>.
- * You may override this default by explicitly specifying the 'class' option in the configuration.
- *
- * You may also enable or disable a module by specifying the 'enabled' option in the configuration.
- *
- * @param {Array} modules module configurations.
- */
- Yii.CModule.prototype.setModules = function (modules) {
- var id, module;
- for (id in modules) {
- if (modules.hasOwnProperty(id)) {
- module = modules[id];
- if(php.is_int(id)) {
- id=module;
- module={};
- }
- if(module['class'] === undefined) {
- Yii.setPathOfAlias(id,this.getModulePath()+"/"+id);
- module['class'] = id+'.'+php.ucfirst(id)+'Module';
- }
- if(this._moduleConfig[id] !== undefined) {
- this._moduleConfig[id]=Yii.CMap.mergeArray(this._moduleConfig[id],module);
- }
- else {
- this._moduleConfig[id]=module;
- }
- }
- }
- };
- /**
- * Checks whether the named component exists.
- * @param {String} id application component ID
- * @returns {Boolean} whether the named application component exists (including both loaded and disabled.)
- */
- Yii.CModule.prototype.hasComponent = function (id) {
- return this._components[id] !== undefined || this._componentConfig[id] !== undefined;
- };
- /**
- * Retrieves the named application component.
- * @param {String} id application component ID (case-sensitive)
- * @param {Boolean} createIfNull whether to create the component if it doesn't exist yet. This parameter
- * has been available since version 1.0.6.
- * @returns {CApplicationComponent} the application component instance, null if the application component is disabled or does not exist.
- * @see hasComponent
- */
- Yii.CModule.prototype.getComponent = function (id, createIfNull) {
- var config, component;
- if (createIfNull === undefined) {
- createIfNull = true;
- }
- if(this._components[id] !== undefined) {
- return this._components[id];
- }
- else if(this._componentConfig[id] !== undefined && createIfNull) {
- config=this._componentConfig[id];
- if(config.enabled === undefined || config.enabled) {
- Yii.trace("Loading \"" + id + "\" application component",'system.CModule');
-
- delete config.enabled;
- component=Yii.createComponent(config);
-
- component.init();
- return (this._components[id]=component);
- }
- }
-
- };
- /**
- * Puts a component under the management of the module.
- * The component will be initialized by calling its {@link CApplicationComponent::init() init()}
- * method if it has not done so.
- * @param {String} id component ID
- * @param {CApplicationComponent} component the component to be added to the module.
- * If this parameter is null, it will unload the component from the module.
- */
- Yii.CModule.prototype.setComponent = function (id, component) {
- if(component===null) {
- delete this._components[id];
- }
- else {
- this._components[id]=component;
- if(!component.getIsInitialized()) {
- component.init();
- }
- }
- };
- /**
- * Returns the application components.
- * @param {Boolean} loadedOnly whether to return the loaded components only. If this is set false,
- * then all components specified in the configuration will be returned, whether they are loaded or not.
- * Loaded components will be returned as objects, while unloaded components as configuration arrays.
- * This parameter has been available since version 1.1.3.
- * @returns {Array} the application components (indexed by their IDs)
- */
- Yii.CModule.prototype.getComponents = function (loadedOnly) {
- if (loadedOnly === undefined) {
- loadedOnly = true;
- }
- if(loadedOnly) {
- return this._components;
- }
- else {
- return php.array_merge(this._componentConfig, this._components);
- }
- };
- /**
- * Sets the application components.
- *
- * When a configuration is used to specify a component, it should consist of
- * the component's initial property values (name-value pairs). Additionally,
- * a component can be enabled (default) or disabled by specifying the 'enabled' value
- * in the configuration.
- *
- * If a configuration is specified with an ID that is the same as an existing
- * component or configuration, the existing one will be replaced silently.
- *
- * The following is the configuration for two components:
- * <pre>
- * {
- * 'db':{
- * 'class':'CDbConnection',
- * 'connectionString':'sqlite:path/to/file.db',
- * },
- * 'cache':{
- * 'class':'CDbCache',
- * 'connectionID':'db',
- * 'enabled':!YII_DEBUG, // enable caching in non-debug mode
- * ),
- * }
- * </pre>
- *
- * @param {Array} components application components(id=>component configuration or instances)
- * @param {Boolean} merge whether to merge the new component configuration with the existing one.
- * Defaults to true, meaning the previously registered component configuration of the same ID
- * will be merged with the new configuration. If false, the existing configuration will be replaced completely.
- */
- Yii.CModule.prototype.setComponents = function (components, merge) {
- var component, id;
- if (merge === undefined) {
- merge = true;
- }
- for (id in components) {
- if (components.hasOwnProperty(id)) {
- component = components[id];
- if(component instanceof Yii.CApplicationComponent) {
- this.setComponent(id,component);
- }
- else if(this._componentConfig[id] !== undefined && merge) {
- this._componentConfig[id]=Yii.CMap.prototype.mergeArray(this._componentConfig[id],component);
- }
- else {
- this._componentConfig[id]=component;
- }
- }
- }
- };
- /**
- * Configures the module with the specified configuration.
- * @param {Array} config the configuration array
- */
- Yii.CModule.prototype.configure = function (config) {
- var key, value;
- if(typeof config === 'object') {
- for (key in config) {
- if (config.hasOwnProperty(key)) {
- value = config[key];
- this.set(key,value);
- }
- }
- }
- };
- /**
- * Loads static application components.
- */
- Yii.CModule.prototype.preloadComponents = function () {
- var i, id;
- for (i in this.preload) {
- if (this.preload.hasOwnProperty(i)) {
- id = this.preload[i];
- this.getComponent(id);
- }
- }
- };
- /**
- * Preinitializes the module.
- * This method is called at the beginning of the module constructor.
- * You may override this method to do some customized preinitialization work.
- * Note that at this moment, the module is not configured yet.
- * @see init
- */
- Yii.CModule.prototype.preinit = function () {
- };
- /**
- * Initializes the module.
- * This method is called at the end of the module constructor.
- * Note that at this moment, the module has been configured, the behaviors
- * have been attached and the application components have been registered.
- * @see preinit
- */
- Yii.CModule.prototype.init = function () {
- Yii.forEach(this.delegates, function(i, item) {
- jQuery("body").undelegate(item[0], item[1]).delegate(item[0], item[1], item[2]);
- });
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CList implements an integer-indexed collection class.
- *
- * You can access, append, insert, remove an item by using
- * {@link itemAt}, {@link add}, {@link insertAt}, {@link remove}, and {@link removeAt}.
- * To get the number of the items in the list, use {@link getCount}.
- * CList can also be used like a regular array as follows,
- * <pre>
- * list.push(item); // append at the end
- * list[index]=item; // $index must be between 0 and $list->Count
- * delete list[index]; // remove the item at $index
- * if(list[index] !== undefined) { // if the list has an item at $index
- * for (index in list) // traverse each item in the list
- * n=php.count(list);
- * } // returns the number of items in the list
- * </pre>
- *
- * To extend CList by doing additional operations with each addition or removal
- * operation (e.g. performing type check), override {@link insertAt()}, and {@link removeAt()}.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CList.php 3001 2011-02-24 16:42:44Z alexander.makarow $
- * @package system.collections
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CComponent
- */
- Yii.CList = function CList (data, readOnly) {
- if (data !== false) {
- this.construct(data, readOnly);
- }
-
- };
- Yii.CList.prototype = new Array();
- Yii.CList.prototype.constructor = Yii.CList;
- Yii.augment(Yii.CList, Yii.CComponent);
- /**
- * @var {Boolean} whether this list is read-only
- */
- Yii.CList.prototype._r = false;
- /**
- * Constructor.
- * Initializes the list with an array or an iterable object.
- * @param {Array} data the initial data. Default is null, meaning no initialization.
- * @param {Boolean} readOnly whether the list is read-only
- * @throws {Yii.CException} If data is not null and neither an array nor an iterator.
- */
- Yii.CList.prototype.construct = function (data, readOnly) {
- if (data === undefined) {
- data = null;
- }
- if (readOnly === undefined) {
- readOnly = false;
- }
- if(data!==null) {
- this.copyFrom(data);
- }
- this.setReadOnly(readOnly);
- };
- /**
- * @returns {Boolean} whether this list is read-only or not. Defaults to false.
- */
- Yii.CList.prototype.getReadOnly = function () {
- return this._r;
- };
- /**
- * @param {Boolean} value whether this list is read-only or not
- */
- Yii.CList.prototype.setReadOnly = function (value) {
- this._r=value;
- };
- /**
- * Returns the number of items in the list.
- * @returns {Integer} the number of items in the list
- */
- Yii.CList.prototype.getCount = function () {
- return this.length;
- };
- /**
- * Returns the item at the specified offset.
- * This method is exactly the same as {@link offsetGet}.
- * @param {Integer} index the index of the item
- * @returns {Mixed} the item at the index
- * @throws {Yii.CException} if the index is out of the range
- */
- Yii.CList.prototype.itemAt = function (index) {
- if(this[index] !== undefined) {
- return this[index];
- }
- else {
- throw new Yii.CException(Yii.t('yii','List index "{index}" is out of bound.',
- {'{index}':index}));
- }
- };
- /**
- * Appends an item at the end of the list.
- * @param {Mixed} item new item
- * @returns {Integer} the zero-based index at which the item is added
- */
- Yii.CList.prototype.add = function (item) {
- return this.push(item);
- };
-
- /**
- * Appends an item at the end of the list, fails if the list is read only.
- * @param {Mixed} item new item
- * @returns {Integer} the zero-based index at which the item is added
- */
- Yii.CList.prototype.push = function (item) {
- if (!this._r) {
- return Array.prototype.push.call(this, item);
- }
- else {
- throw new Yii.CException(Yii.t('yii','The list is read only.'));
- }
- };
-
- /**
- * Pops an item off the end of the list, fails if the list is read only.
- * @returns {Mixed} the popped item
- */
- Yii.CList.prototype.pop = function () {
- if (!this._r) {
- return Array.prototype.pop.call(this);
- }
- else {
- throw new Yii.CException(Yii.t('yii','The list is read only.'));
- }
- };
-
- /**
- * Shifts an item off the start of the list, fails if the list is read only.
- * @returns {Mixed} the shifted item
- */
- Yii.CList.prototype.shift = function () {
- if (!this._r) {
- return Array.prototype.shift.call(this);
- }
- else {
- throw new Yii.CException(Yii.t('yii','The list is read only.'));
- }
- };
- /**
- * Inserts an item at the specified position.
- * Original item at the position and the next items
- * will be moved one step towards the end.
- * @param {Integer} index the specified position.
- * @param {Mixed} item new item
- * @throws {Yii.CException} If the index specified exceeds the bound or the list is read-only
- */
- Yii.CList.prototype.insertAt = function (index, item) {
- if(!this._r)
- {
- if(index===this.length) {
- this[this.length + 1]=item;
- }
- else if(index>=0 && index<this.length)
- {
- php.array_splice(this,index,0,[item]);
- }
- else {
- throw new Yii.CException(Yii.t('yii','List index "{index}" is out of bound.',
- {'{index}':index}));
- }
- }
- else {
- throw new Yii.CException(Yii.t('yii','The list is read only.'));
- }
- };
- /**
- * Removes an item from the list.
- * The list will first search for the item.
- * The first item found will be removed from the list.
- * @param {Mixed} item the item to be removed.
- * @returns {Integer} the index at which the item is being removed
- * @throws {Yii.CException} If the item does not exist
- */
- Yii.CList.prototype.remove = function (item) {
- var index;
- if((index=this.indexOf(item))>=0)
- {
- this.removeAt(index);
- return index;
- }
- else {
- return false;
- }
- };
- /**
- * Removes an item at the specified position.
- * @param {Integer} index the index of the item to be removed.
- * @returns {Mixed} the removed item.
- * @throws {Yii.CException} If the index specified exceeds the bound or the list is read-only
- */
- Yii.CList.prototype.removeAt = function (index) {
- var item;
- if(!this._r) {
- if(index>=0 && index<this.length) {
- if(index===this.length) {
- return this.pop();
- }
- else
- {
- item=this[index];
- php.array_splice(this,index,1);
- return item;
- }
- }
- else {
- throw new Yii.CException(Yii.t('yii','List index "{index}" is out of bound.',
- {'{index}':index}));
- }
- }
- else {
- throw new Yii.CException(Yii.t('yii','The list is read only.'));
- }
- };
- /**
- * Removes all items in the list.
- */
- Yii.CList.prototype.clear = function () {
- var i;
- for(i=this.length - 1; i >= 0; --i) {
- this.removeAt(i);
- }
- };
- /**
- * @param {Mixed} item the item
- * @returns {Boolean} whether the list contains the item
- */
- Yii.CList.prototype.contains = function (item) {
- return this.indexOf(item) >= 0;
- };
- /**
- * @returns {Array} the list of items in array
- */
- Yii.CList.prototype.toArray = function () {
- var ret = [], i, limit;
- limit = this.length;
- for (i = 0; i < limit; i++) {
- ret.push(this[i]);
- }
- return ret;
- };
- /**
- * Copies iterable data into the list.
- * Note, existing data in the list will be cleared first.
- * @param {Mixed} data the data to be copied from, must be an array or object implementing Traversable
- * @throws {Yii.CException} If data is neither an array nor a Traversable.
- */
- Yii.CList.prototype.copyFrom = function (data) {
- var i, item, limit;
- if(Object.prototype.toString.call(data) === '[object Array]' || (data instanceof Array)) {
- if(this.length > 0) {
- this.clear();
- }
- if(data instanceof Yii.CList) {
- data=data.toArray();
- }
- for (i = 0, limit = data.length; i < limit; i++) {
- item = data[i];
- this.add(item);
- }
- }
- else if(data!==null) {
- throw new Yii.CException(Yii.t('yii','List data must be an array or an object implementing Traversable.'));
- }
- };
- /**
- * Merges iterable data into the map.
- * New data will be appended to the end of the existing data.
- * @param {Mixed} data the data to be merged with, must be an array or object implementing Traversable
- * @throws {Yii.CException} If data is neither an array nor an iterator.
- */
- Yii.CList.prototype.mergeWith = function (data) {
- var i, item;
- if(Object.prototype.toString.call(data) === '[object Array]' || (data instanceof Array))
- {
- if(data instanceof Yii.CList) {
- data=data.toArray();
- }
- for (i in data) {
- if (data.hasOwnProperty(i)) {
- item = data[i];
- this.add(item);
- }
- }
- }
- else if(data!==null) {
- throw new Yii.CException(Yii.t('yii','List data must be an array or an object implementing Traversable.'));
- }
- };
- /**
- * Provides convenient access to Yii.forEach()
- * @param {Function} callback The callback function, this will receive 2 parameters, key and value
- * @returns {Yii.CList} the list
- */
- Yii.CList.prototype.forEach = function(callback) {
- return Yii.forEach(this,callback);
- };
- /*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CMap implements a collection that takes key-value pairs.
- *
- * You can access, add or remove an item with a key by using
- * {@link itemAt}, {@link add}, and {@link remove}.
- * To get the number of the items in the map, use {@link getCount}.
- * CMap can also be used like a regular array as follows,
- * <pre>
- * map[key]=value; // add a key-value pair
- * delete map[key]; // remove the value with the specified key
- * if(map[key] !== undefined) { // if the map contains the key
- * for (key in map) // traverse the items in the map
- * n=php.count(map);
- * } // returns the number of items in the map
- * </pre>
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CMap.php 3153 2011-04-01 12:50:06Z qiang.xue $
- * @package system.collections
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CComponent
- */
- Yii.CMap = function CMap (data, readOnly) {
- if (data !== false) {
- this.construct(data, readOnly);
- }
-
- };
- Yii.CMap.prototype = new Yii.CComponent();
- Yii.CMap.prototype.constructor = Yii.CMap;
- /**
- * Constructor.
- * Initializes the list with an array or an iterable object.
- * @param {Object} data the intial data. Default is null, meaning no initialization.
- * @throws {Yii.CException} If data is not null and neither an array nor an iterator.
- */
- Yii.CMap.prototype.construct = function (data) {
- if (data === undefined) {
- data = null;
- }
-
- if(data!==null) {
- this.copyFrom(data);
- }
- };
- /**
- * Returns the number of items in the map.
- * @returns {Integer} number of items in the map.
- */
- Yii.CMap.prototype.count = function () {
- return this.getCount();
- };
- /**
- * Returns the number of items in the map.
- * @returns {Integer} the number of items in the map
- */
- Yii.CMap.prototype.getCount = function () {
- var total = 0, i;
- for (i in this) {
- if (this.hasOwnProperty(i)) {
- total++;
- }
- }
-
- return total;
- };
- /**
- * @returns {Array} the key list
- */
- Yii.CMap.prototype.getKeys = function () {
- var i, keys = [];
- for (i in this) {
- if (this.hasOwnProperty(i)) {
- keys.push(i);
- }
- }
- return keys;
- };
- /**
- * Returns the item with the specified key.
- * @param {Mixed} key the key
- * @returns {Mixed} the element at the offset, null if no element is found at the offset
- */
- Yii.CMap.prototype.itemAt = function (key) {
- if(this[key] !== undefined) {
- return this[key];
- }
- else {
- return null;
- }
- };
- /**
- * Adds an item into the map.
- * Note, if the specified key already exists, the old value will be overwritten.
- * @param {Mixed} key key
- * @param {Mixed} value value
- * @throws {Yii.CException} if the map is read-only
- */
- Yii.CMap.prototype.add = function (key, value) {
- if (key === null) {
- key = this.count();
- }
- this[key] = value;
- };
- /**
- * Removes an item from the map by its key.
- * @param {Mixed} key the key of the item to be removed
- * @returns {Mixed} the removed value, null if no such key exists.
- * @throws {Yii.CException} if the map is read-only
- */
- Yii.CMap.prototype.remove = function (key) {
- var value;
- if(this[key] !== undefined) {
- value=this[key];
- delete this[key];
- return value;
- }
- };
- /**
- * Removes all items in the map.
- */
- Yii.CMap.prototype.clear = function () {
- var i, keyList, key;
- for (i in this) {
- if (this.hasOwnProperty(i)) {
- this.remove(i);
- }
- }
- };
- /**
- * @param {Mixed} key the key
- * @returns {Boolean} whether the map contains an item with the specified key
- */
- Yii.CMap.prototype.contains = function (key) {
- return this[key] !== undefined;
- };
- /**
- * @returns {Array} the list of items in array
- */
- Yii.CMap.prototype.toArray = function () {
- var i, ret = [];
- for (i in this) {
- if (this.hasOwnProperty(i)) {
- ret.push(this[i]);
- }
- }
- return ret;
- };
- /**
- * @returns {Object} the list of items in object
- */
- Yii.CMap.prototype.toObject = function () {
- var i, ret = {};
- for (i in this) {
- if (this.hasOwnProperty(i)) {
- ret[i] = this[i];
- }
- }
- return ret;
- };
- /**
- * Copies iterable data into the map.
- * Note, existing data in the map will be cleared first.
- * @param {Mixed} data the data to be copied from, must be an array or object implementing Traversable
- * @throws {Yii.CException} If data is neither an array nor an iterator.
- */
- Yii.CMap.prototype.copyFrom = function (data) {
- var key, value;
- if(typeof data === "object") {
- if(this.getCount()>0) {
- this.clear();
- }
- if(data instanceof Yii.CMap) {
- data=data.toObject();
- }
- for (key in data) {
- if (data.hasOwnProperty(key)) {
- value = data[key];
- this.add(key,value);
- }
- }
- }
- else if(data!==null) {
- throw new Yii.CException(Yii.t('yii','Map data must be an array or an object implementing Traversable.'));
- }
- };
- /**
- * Merges iterable data into the map.
- *
- * Existing elements in the map will be overwritten if their keys are the same as those in the source.
- * If the merge is recursive, the following algorithm is performed:
- * <ul>
- * <li>the map data is saved as $a, and the source data is saved as $b;</li>
- * <li>if $a and $b both have an array indxed at the same string key, the arrays will be merged using this algorithm;</li>
- * <li>any integer-indexed elements in $b will be appended to $a and reindxed accordingly;</li>
- * <li>any string-indexed elements in $b will overwrite elements in $a with the same index;</li>
- * </ul>
- *
- * @param {Mixed} data the data to be merged with, must be an array or object implementing Traversable
- * @param {Boolean} recursive whether the merging should be recursive.
- *
- * @throws {Yii.CException} If data is neither an array nor an iterator.
- */
- Yii.CMap.prototype.mergeWith = function (data, recursive) {
- var d, key, value;
- if (recursive === undefined) {
- recursive = true;
- }
- if(typeof data === "object") {
- if(data instanceof Yii.CMap) {
- data=data.toObject();
- }
- else if(data instanceof Yii.CList) {
- data=data.toArray();
- }
- if(recursive) {
- this.mergeArray(this,data);
- }
- else
- {
- for (key in data) {
- if (data.hasOwnProperty(key)) {
- value = data[key];
- this.add(key,value);
- }
- }
- }
- }
- else if(data!==null) {
- throw new Yii.CException(Yii.t('yii','Map data must be an array or an object implementing Traversable.'));
- }
- };
- /**
- * Merges two arrays into one recursively.
- * If each array has an element with the same string key value, the latter
- * will overwrite the former (different from array_merge_recursive).
- * Recursive merging will be conducted if both arrays have an element of array
- * type and are having the same key.
- * For integer-keyed elements, the elements from the latter array will
- * be appended to the former array.
- * @param {Array} a array to be merged to
- * @param {Array} b array to be merged from
- * @returns {Array} the merged array (the original arrays are not changed.)
- * @see mergeWith
- */
- Yii.CMap.prototype.mergeArray = function (a, b) {
- var k, v;
- for (k in b) {
- if (b.hasOwnProperty(k)) {
- v = b[k];
- if((typeof(k) === 'number' && (k % 1 ? false : true))) {
- a[k] !== undefined ? a.push(v) : a[k]=v;
- }
- else if (a[k] !== undefined && typeof a[k] === "object") {
- a[k]=this.mergeArray(a[k],v);
- }
- else {
- a[k]=v;
- }
- }
- }
- return a;
- };
- /**
- * Provides convenient access to Yii.forEach()
- * @param {Function} callback The callback function, this will receive 2 parameters, key and value
- * @returns {Yii.CMap} the map
- */
- Yii.CMap.prototype.forEach = function(callback) {
- return Yii.forEach(this,callback);
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CValidator is the base class for all validators.
- *
- * Child classes must implement the {@link validateAttribute} method.
- *
- * The following properties are defined in CValidator:
- * <ul>
- * <li>{@link attributes}: array, list of attributes to be validated;</li>
- * <li>{@link message}: string, the customized error message. The message
- * may contain placeholders that will be replaced with the actual content.
- * For example, the "{attribute}" placeholder will be replaced with the label
- * of the problematic attribute. Different validators may define additional
- * placeholders.</li>
- * <li>{@link on}: string, in which scenario should the validator be in effect.
- * This is used to match the 'on' parameter supplied when calling {@link CModel::validate}.</li>
- * </ul>
- *
- * When using {@link createValidator} to create a validator, the following aliases
- * are recognized as the corresponding built-in validator classes:
- * <ul>
- * <li>required: {@link CRequiredValidator}</li>
- * <li>filter: {@link CFilterValidator}</li>
- * <li>match: {@link CRegularExpressionValidator}</li>
- * <li>email: {@link CEmailValidator}</li>
- * <li>url: {@link CUrlValidator}</li>
- * <li>unique: {@link CUniqueValidator}</li>
- * <li>compare: {@link CCompareValidator}</li>
- * <li>length: {@link CStringValidator}</li>
- * <li>in: {@link CRangeValidator}</li>
- * <li>numerical: {@link CNumberValidator}</li>
- * <li>captcha: {@link CCaptchaValidator}</li>
- * <li>type: {@link CTypeValidator}</li>
- * <li>file: {@link CFileValidator}</li>
- * <li>default: {@link CDefaultValueValidator}</li>
- * <li>exist: {@link CExistValidator}</li>
- * <li>boolean: {@link CBooleanValidator}</li>
- * <li>date: {@link CDateValidator}</li>
- * <li>safe: {@link CSafeValidator}</li>
- * <li>unsafe: {@link CUnsafeValidator}</li>
- * </ul>
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CValidator.php 3160 2011-04-03 01:08:23Z qiang.xue $
- * @package system.validators
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CComponent
- */
- Yii.CValidator = function CValidator() {
- };
- Yii.CValidator.prototype = new Yii.CComponent();
- Yii.CValidator.prototype.constructor = Yii.CValidator;
- /**
- * @var {Object} list of built-in validators (name=>class)
- */
- Yii.CValidator.prototype.builtInValidators = {
- 'required':'Yii.CRequiredValidator',
- 'filter':'Yii.CFilterValidator',
- 'match':'Yii.CRegularExpressionValidator',
- 'email':'Yii.CEmailValidator',
- 'url':'Yii.CUrlValidator',
- 'unique':'Yii.CUniqueValidator',
- 'compare':'Yii.CCompareValidator',
- 'length':'Yii.CStringValidator',
- 'in':'Yii.CRangeValidator',
- 'numerical':'Yii.CNumberValidator',
- 'captcha':'Yii.CCaptchaValidator',
- 'type':'Yii.CTypeValidator',
- 'file':'Yii.CFileValidator',
- 'default':'Yii.CDefaultValueValidator',
- 'exist':'Yii.CExistValidator',
- 'boolean':'Yii.CBooleanValidator',
- 'safe':'Yii.CSafeValidator',
- 'unsafe':'Yii.CUnsafeValidator',
- 'date':'Yii.CDateValidator'
- };
- /**
- * @var {Array} list of attributes to be validated.
- */
- Yii.CValidator.prototype.attributes = null;
- /**
- * @var {String} the user-defined error message. Different validators may define various
- * placeholders in the message that are to be replaced with actual values. All validators
- * recognize "{attribute}" placeholder, which will be replaced with the label of the attribute.
- */
- Yii.CValidator.prototype.message = null;
- /**
- * @var {Boolean} whether this validation rule should be skipped if when there is already a validation
- * error for the current attribute. Defaults to false.
- * @since 1.1.1
- */
- Yii.CValidator.prototype.skipOnError = false;
- /**
- * @var {Array} list of scenarios that the validator should be applied.
- * Each array value refers to a scenario name with the same name as its array key.
- */
- Yii.CValidator.prototype.on = null;
- /**
- * @var {Boolean} whether attributes listed with this validator should be considered safe for massive assignment.
- * Defaults to true.
- * @since 1.1.4
- */
- Yii.CValidator.prototype.safe = true;
- /**
- * @var {Boolean} whether to perform client-side validation. Defaults to true.
- * Please refer to {@link CActiveForm::enableClientValidation} for more details about client-side validation.
- * @since 1.1.7
- */
- Yii.CValidator.prototype.enableClientValidation = true;
- /**
- * Validates a single attribute.
- * This method should be overridden by child classes.
- * @param {Yii.CModel} object the data object being validated
- * @param {String} attribute the name of the attribute to be validated.
- */
- Yii.CValidator.prototype.validateAttribute = function (object, attribute) {
- };
- /**
- * Creates a validator object.
- * @param {String} name the name or class of the validator
- * @param {Yii.CModel} object the data object being validated that may contain the inline validation method
- * @param {Mixed} attributes list of attributes to be validated. This can be either an array of
- * the attribute names or a string of comma-separated attribute names.
- * @param {Array} params initial values to be applied to the validator properties
- * @returns {Yii.CValidator} the validator
- */
- Yii.CValidator.prototype.createValidator = function (name, object, attributes, params) {
- var n, on, validator, builtInValidators, className, value, nameParts, i, limit, classObject;
- if (params === undefined) {
- params = [];
- }
- if(typeof(attributes) === 'string') {
- attributes=attributes.split(/[\s,]+/);
- }
- if(params.on !== undefined) {
- if(Object.prototype.toString.call(params.on) === '[object Array]') {
- on=params.on;
- }
- else {
- on=params.on.split(/[\s,]+/);
- }
- }
- else {
- on=[];
- }
- if (object[name] !== undefined && typeof object[name] === "function") {
- validator=new Yii.CInlineValidator();
- validator.attributes=attributes;
- validator.method=name;
- validator.params=params;
- if(params.skipOnError !== undefined) {
- validator.skipOnError=params.skipOnError;
- }
- }
- else {
- params.attributes = attributes;
- if(this.builtInValidators[name] !== undefined) {
- className = this.builtInValidators[name];
- }
- else {
- className = name;
- }
-
- if (className.slice(0,3) === "Yii") {
-
- validator=new Yii[className.slice(4)]();
-
- }
- else {
- validator = new window[className]();
- }
- for (n in params) {
- if (params.hasOwnProperty(n)) {
- value = params[n];
- validator[n]=value;
- }
- }
-
- }
- validator.on=php.empty(on) ? [] : php.array_combine(on,on);
- return validator;
- };
- /**
- * Validates the specified object.
- * @param {Yii.CModel} object the data object being validated
- * @param {Array} attributes the list of attributes to be validated. Defaults to null,
- * meaning every attribute listed in {@link attributes} will be validated.
- */
- Yii.CValidator.prototype.validate = function (object, attributes) {
- var i, attribute, self = this;
-
- if (attributes === undefined) {
- attributes = null;
- }
- if(Object.prototype.toString.call(attributes) === '[object Array]') {
- attributes=php.array_intersect(this.attributes,attributes);
- }
- else {
- attributes=this.attributes;
- }
-
- Yii.forEach(attributes, function(i,attribute) {
- if(!self.skipOnError || !object.hasErrors(attribute)) {
- self.validateAttribute(object,attribute);
- }
- });
-
- };
- /**
- * Returns the JavaScript needed for performing client-side validation.
- * Do not override this method if the validator does not support client-side validation.
- * Two predefined JavaScript variables can be used:
- * <ul>
- * <li>value: the value to be validated</li>
- * <li>messages: an array used to hold the validation error messages for the value</li>
- * </ul>
- * @param {Yii.CModel} object the data object being validated
- * @param {String} attribute the name of the attribute to be validated.
- * @returns {String} the client-side validation script. Null if the validator does not support client-side validation.
- * @see CActiveForm::enableClientValidation
- * @since 1.1.7
- */
- Yii.CValidator.prototype.clientValidateAttribute = function (object, attribute) {
- };
- /**
- * Returns a value indicating whether the validator applies to the specified scenario.
- * A validator applies to a scenario as long as any of the following conditions is met:
- * <ul>
- * <li>the validator's "on" property is empty</li>
- * <li>the validator's "on" property contains the specified scenario</li>
- * </ul>
- * @param {String} scenario scenario name
- * @returns {Boolean} whether the validator applies to the specified scenario.
- * @since 1.0.2
- */
- Yii.CValidator.prototype.applyTo = function (scenario) {
- return php.empty(this.on) || this.on[scenario] !== undefined;
- };
- /**
- * Adds an error about the specified attribute to the active record.
- * This is a helper method that performs message selection and internationalization.
- * @param {Yii.CModel} object the data object being validated
- * @param {String} attribute the attribute being validated
- * @param {String} message the error message
- * @param {Array} params values for the placeholders in the error message
- */
- Yii.CValidator.prototype.addError = function (object, attribute, message, params) {
- if (params === undefined) {
- params = [];
- }
- params['{attribute}']=object.getAttributeLabel(attribute);
-
- object.addError(attribute,php.strtr(message,params));
- };
- /**
- * Checks if the given value is empty.
- * A value is considered empty if it is null, an empty array, or the trimmed result is an empty string.
- * Note that this method is different from PHP empty(). It will return false when the value is 0.
- * @param {Mixed} value the value to be checked
- * @param {Boolean} trim whether to perform trimming before checking if the string is empty. Defaults to false.
- * @returns {Boolean} whether the value is empty
- * @since 1.0.9
- */
- Yii.CValidator.prototype.isEmpty = function (value, trim) {
- if (trim === undefined) {
- trim = false;
- }
- return value===null || value===[] || value==='' || trim && (/boolean|number|string/).test(typeof value) && php.trim(value)==='';
- }/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CMessageSource is the base class for message translation repository classes.
- *
- * A message source is an application component that provides message internationalization (i18n).
- * It stores messages translated in different languages and provides
- * these translated versions when requested.
- *
- * A concrete class must implement {@link loadMessages} or override {@link translateMessage}.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CMessageSource.php 2798 2011-01-01 19:29:03Z qiang.xue $
- * @package system.i18n
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CApplicationComponent
- */
- Yii.CMessageSource = function CMessageSource () {
-
- };
- Yii.CMessageSource.prototype = new Yii.CApplicationComponent();
- Yii.CMessageSource.prototype.constructor = Yii.CMessageSource;
- /**
- * @var {Boolean} whether to force message translation when the source and target languages are the same.
- * Defaults to false, meaning translation is only performed when source and target languages are different.
- * @since 1.1.4
- */
- Yii.CMessageSource.prototype.forceTranslation = false;
- Yii.CMessageSource.prototype._language = null;
- Yii.CMessageSource.prototype._messages = {};
- /**
- * Loads the message translation for the specified language and category.
- * @param {String} category the message category
- * @param {String} language the target language
- * @returns {Object} the loaded messages
- */
- Yii.CMessageSource.prototype.loadMessages = function (category, language) {
- };
- /**
- * @returns {String} the language that the source messages are written in.
- * Defaults to {@link CApplication::language application language}.
- */
- Yii.CMessageSource.prototype.getLanguage = function () {
- return this._language===null ? Yii.app().sourceLanguage : this._language;
- };
- /**
- * @param {String} language the language that the source messages are written in.
- */
- Yii.CMessageSource.prototype.setLanguage = function (language) {
- this._language=Yii.CLocale.prototype.getCanonicalID(language);
- };
- /**
- * Translates a message to the specified language.
- *
- * Note, if the specified language is the same as
- * the {@link getLanguage source message language}, messages will NOT be translated.
- *
- * If the message is not found in the translations, an {@link onMissingTranslation}
- * event will be raised. Handlers can mark this message or do some
- * default handling. The {@link CMissingTranslationEvent::message}
- * property of the event parameter will be returned.
- *
- * @param {String} category the message category
- * @param {String} message the message to be translated
- * @param {String} language the target language. If null (default), the {@link CApplication::getLanguage application language} will be used.
- * This parameter has been available since version 1.0.3.
- * @returns {String} the translated message (or the original message if translation is not needed)
- */
- Yii.CMessageSource.prototype.translate = function (category, message, language) {
- if (language === undefined) {
- language = null;
- }
- if(language===null) {
- language=Yii.app().getLanguage();
- }
- if(this.forceTranslation || language!==this.getLanguage()) {
- return this.translateMessage(category,message,language);
- }
- else {
- return message;
- }
- };
- /**
- * Translates the specified message.
- * If the message is not found, an {@link onMissingTranslation}
- * event will be raised.
- * @param {String} category the category that the message belongs to
- * @param {String} message the message to be translated
- * @param {String} language the target language
- * @returns {String} the translated message
- */
- Yii.CMessageSource.prototype.translateMessage = function (category, message, language) {
- var key, event;
- key=language+'.'+category;
- if(this._messages[key] === undefined) {
- this._messages[key]=this.loadMessages(category,language);
- }
- if(this._messages[key][message] !== undefined && this._messages[key][message]!=='') {
- return this._messages[key][message];
- }
- else if(this.hasEventHandler('onMissingTranslation'))
- {
- event=new Yii.CMissingTranslationEvent(this,category,message,language);
- this.onMissingTranslation(event);
- return event.message;
- }
- else {
- return message;
- }
- };
- /**
- * Raised when a message cannot be translated.
- * Handlers may log this message or do some default handling.
- * The {@link CMissingTranslationEvent::message} property
- * will be returned by {@link translateMessage}.
- * @param {Yii.CMissingTranslationEvent} event the event parameter
- */
- Yii.CMessageSource.prototype.onMissingTranslation = function (event) {
- this.raiseEvent('onMissingTranslation',event);
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CFilter is the base class for all filters.
- *
- * A filter can be applied before and after an action is executed.
- * It can modify the context that the action is to run or decorate the result that the
- * action generates.
- *
- * Override {@link preFilter()} to specify the filtering logic that should be applied
- * before the action, and {@link postFilter()} for filtering logic after the action.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CFilter.php 2799 2011-01-01 19:31:13Z qiang.xue $
- * @package system.web.filters
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CComponent
- */
- Yii.CFilter = function CFilter () {
- };
- Yii.CFilter.prototype = new Yii.CComponent();
- Yii.CFilter.prototype.constructor = Yii.CFilter;
- /**
- * Performs the filtering.
- * The default implementation is to invoke {@link preFilter}
- * and {@link postFilter} which are meant to be overridden
- * child classes. If a child class needs to override this method,
- * make sure it calls <code>$filterChain->run()</code>
- * if the action should be executed.
- * @param {Yii.CFilterChain} filterChain the filter chain that the filter is on.
- */
- Yii.CFilter.prototype.filter = function (filterChain) {
- if(this.preFilter(filterChain))
- {
- filterChain.run();
- this.postFilter(filterChain);
- }
- };
- /**
- * Initializes the filter.
- * This method is invoked after the filter properties are initialized
- * and before {@link preFilter} is called.
- * You may override this method to include some initialization logic.
- * @since 1.1.4
- */
- Yii.CFilter.prototype.init = function () {
- };
- /**
- * Performs the pre-action filtering.
- * @param {Yii.CFilterChain} filterChain the filter chain that the filter is on.
- * @returns {Boolean} whether the filtering process should continue and the action
- * should be executed.
- */
- Yii.CFilter.prototype.preFilter = function (filterChain) {
- return true;
- };
- /**
- * Performs the post-action filtering.
- * @param {Yii.CFilterChain} filterChain the filter chain that the filter is on.
- */
- Yii.CFilter.prototype.postFilter = function (filterChain) {
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CViewRenderer is the base class for view renderer classes.
- *
- * A view renderer is an application component that renders views written
- * in a customized syntax.
- *
- * Once installing a view renderer as a 'viewRenderer' application component,
- * the normal view rendering process will be intercepted by the renderer.
- * The renderer will first parse the source view file and then render the
- * the resulting view file.
- *
- * Parsing results are saved as temporary files that may be stored
- * under the application runtime directory or together with the source view file.
- *
- * @originalAuthor Steve Heyns http://customgothic.com/
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CViewRenderer.php 2799 2011-01-01 19:31:13Z qiang.xue $
- * @package system.web.renderers
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CApplicationComponent
- */
- Yii.CViewRenderer = function CViewRenderer () {
- };
- Yii.CViewRenderer.prototype = new Yii.CApplicationComponent();
- Yii.CViewRenderer.prototype.constructor = Yii.CViewRenderer;
- /**
- * @var {String} the extension name of the view file. Defaults to '.html'.
- * @since 1.0.9
- */
- Yii.CViewRenderer.prototype.fileExtension = '.html';
- /**
- * Renders a view file.
- * @param {Yii.CBaseController} context the controller or widget who is rendering the view file.
- * @param {String} sourceFile the view file path
- * @param {Mixed} data the data to be passed to the view
- * @param {Boolean} returnVar whether the rendering result should be returned
- * @returns {Mixed} the rendering result, or null if the rendering result is not needed.
- */
- Yii.CViewRenderer.prototype.renderFile = function (context, sourceFile, data, returnVar) {
- var file, viewFile;
-
- viewFile=this.getViewFile(sourceFile);
-
- return context.renderInternal(viewFile,data,returnVar);
- };
- /**
- * Generates the resulting view file path.
- * @param {String} file source view file path
- * @returns {String} resulting view file path
- */
- Yii.CViewRenderer.prototype.getViewFile = function (file) {
- return file;
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CFormElement is the base class for presenting all kinds of form element.
- *
- * CFormElement implements the way to get and set arbitrary attributes.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CFormElement.php 3001 2011-02-24 16:42:44Z alexander.makarow $
- * @package system.web.form
- * @since 1.1
- * @author Charles Pick
- * @class
- * @extends Yii.CComponent
- */
- Yii.CFormElement = function CFormElement (config, parent) {
- if (config !== false) {
- this.construct(config, parent);
- }
- };
- Yii.CFormElement.prototype = new Yii.CComponent();
- Yii.CFormElement.prototype.constructor = Yii.CFormElement;
- /**
- * @var {Array} list of attributes (name=>value) for the HTML element represented by this object.
- */
- Yii.CFormElement.prototype.attributes = {};
- Yii.CFormElement.prototype._parent = null;
- Yii.CFormElement.prototype._visible = null;
- /**
- * Renders this element.
- * @returns {String} the rendering result
- */
- Yii.CFormElement.prototype.render = function () {
- };
- /**
- * Constructor.
- * @param {Mixed} config the configuration for this element.
- * @param {Mixed} parent the direct parent of this element.
- * @see configure
- */
- Yii.CFormElement.prototype.construct = function (config, parent) {
-
- this.configure(config);
- this._parent=parent;
- };
- /**
- * Converts the object to a string.
- * This is a PHP magic method.
- * The default implementation simply calls {@link render} and return
- * the rendering result.
- * @returns {String} the string representation of this object.
- */
- Yii.CFormElement.prototype.toString = function () {
- return this.render();
- };
- /**
- * Returns a property value or an attribute value.
- * Do not call this method. This is a PHP magic method that we override
- * to allow using the following syntax to read a property or attribute:
- * <pre>
- * value=element.propertyName;
- * value=element.attributeName;
- * </pre>
- * @param {String} name the property or attribute name
- * @returns {Mixed} the property or attribute value
- * @throws {Yii.CException} if the property or attribute is not defined
- * @see __set
- */
- Yii.CFormElement.prototype.get = function (name) {
- var getter;
- getter='get'+php.ucfirst(name);
- if(php.method_exists(this,getter)) {
- return this[getter]();
- }
- else if(this.attributes[name] !== undefined) {
- return this.attributes[name];
- }
- else {
- throw new Yii.CException(Yii.t('yii','Property "{class}.{property}" is not defined.',
- {'{class}':this.getClassName(), '{property}':name}));
- }
- };
- /**
- * Sets value of a property or attribute.
- * Do not call this method. This is a PHP magic method that we override
- * to allow using the following syntax to set a property or attribute.
- * <pre>
- * this.propertyName=value;
- * this.attributeName=value;
- * </pre>
- * @param {String} name the property or attribute name
- * @param {Mixed} value the property or attribute value
- * @see __get
- */
- Yii.CFormElement.prototype.set = function (name, value) {
- var setter;
- setter='set'+php.ucfirst(name);
-
- if(php.method_exists(this,setter)) {
- this[setter](value);
- }
- else if (this[name] !== undefined) {
- this[name] = value;
- }
- else {
- this.attributes[name]=value;
- }
- };
- /**
- * Configures this object with property initial values.
- * @param {Mixed} config the configuration for this object. This can be an array
- * representing the property names and their initial values.
- * It can also be a string representing the file name of the PHP script
- * that returns a configuration array.
- */
- Yii.CFormElement.prototype.configure = function (config) {
- var name, value;
-
- for (name in config) {
- if (config.hasOwnProperty(name)) {
- value = config[name];
- this.set(name,value);
- }
- }
- };
- /**
- * Returns a value indicating whether this element is visible and should be rendered.
- * This method will call {@link evaluateVisible} to determine the visibility of this element.
- * @returns {Boolean} whether this element is visible and should be rendered.
- */
- Yii.CFormElement.prototype.getVisible = function () {
- if(this._visible===null) {
- this._visible=this.evaluateVisible();
- }
- return this._visible;
- };
- /**
- * @param {Boolean} value whether this element is visible and should be rendered.
- */
- Yii.CFormElement.prototype.setVisible = function (value) {
- this._visible=value;
- };
- /**
- * @returns {Mixed} the direct parent of this element. This could be either a {@link CForm} object or a {@link CBaseController} object
- * (a controller or a widget).
- */
- Yii.CFormElement.prototype.getParent = function () {
- return this._parent;
- };
- /**
- * Evaluates the visibility of this element.
- * Child classes should override this method to implement the actual algorithm
- * for determining the visibility.
- * @returns {Boolean} whether this element is visible. Defaults to true.
- */
- Yii.CFormElement.prototype.evaluateVisible = function () {
- return true;
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CBaseController is the base class for {@link CController} and {@link CWidget}.
- *
- * It provides the common functionalities shared by controllers who need to render views.
- *
- * CBaseController also implements the support for the following features:
- * <ul>
- * <li>{@link CClipWidget Clips} : a clip is a piece of captured output that can be inserted elsewhere.</li>
- * <li>{@link CWidget Widgets} : a widget is a self-contained sub-controller with its own view and model.</li>
- * <li>{@link COutputCache Fragment cache} : fragment cache selectively caches a portion of the output.</li>
- * </ul>
- *
- * To use a widget in a view, use the following in the view:
- * <pre>
- * this.widget('path.to.widgetClass',{'property1':'value1',+++});
- * </pre>
- * or
- * <pre>
- * this.beginWidget('path.to.widgetClass',{'property1':'value1',+++});
- * // ... display other contents here
- * this.endWidget();
- * </pre>
- *
- * To create a clip, use the following:
- * <pre>
- * this.beginClip('clipID');
- * // ... display the clip contents
- * this.endClip();
- * </pre>
- * Then, in a different view or place, the captured clip can be inserted as:
- * <pre>
- * document.write(this.clips['clipID']);
- * </pre>
- *
- * To use fragment cache, do as follows,
- * <pre>
- * if(this.beginCache('cacheID',{'property1':'value1',+++})
- * {
- * // ... display the content to be cached here
- * this.endCache();
- * }
- * </pre>
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CBaseController.php 2799 2011-01-01 19:31:13Z qiang.xue $
- * @package system.web
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CComponent
- */
- Yii.CBaseController = function CBaseController() {
- };
- Yii.CBaseController.prototype = new Yii.CComponent();
- Yii.CBaseController.prototype.constructor = Yii.CBaseController;
- Yii.CBaseController.prototype._widgetStack = [];
- /**
- * Returns the view script file according to the specified view name.
- * This method must be implemented by child classes.
- * @param {String} viewName view name
- * @returns {String} the file path for the named view. False if the view cannot be found.
- */
- Yii.CBaseController.prototype.getViewFile = function (viewName) {
- };
- /**
- * Renders a view file.
- *
- * @param {String} viewFile view file path
- * @param {Array} data data to be extracted and made available to the view
- * @param {Function} callback The callback to execute
- * @throws {Yii.CException} if the view file does not exist
- */
- Yii.CBaseController.prototype.renderFile = function (viewFile, data, callback) {
- var renderer;
- if (data === undefined) {
- data = null;
- }
- if((renderer=Yii.app().getViewRenderer())!==undefined && renderer.fileExtension==='.'+(viewFile.split(".").pop())) {
- return renderer.renderFile(this,viewFile,data,callback);
- }
- else {
- return this.renderInternal(viewFile,data,callback);
- }
-
- };
- /**
- * Renders a view file.
- * This method includes the view file as a JavaScript script
- * and captures the display result if required.
- * @param {String} viewFile view file
- * @param {Array} data data to be extracted and made available to the view file
- * @param {Function} callback The callback to execute with the rendering result
- * @returns {String} the rendering result. Null if the rendering result is not required.
- */
- Yii.CBaseController.prototype.renderInternal = function (_viewFile_, _data_, _callback_) {
- var data;
- if (_data_ === undefined) {
- _data_ = null;
- }
-
- return Yii.include(_viewFile_,true, _callback_);
-
- };
- /**
- * Creates a widget and initializes it.
- * This method first creates the specified widget instance.
- * It then configures the widget's properties with the given initial values.
- * At the end it calls {@link CWidget::init} to initialize the widget.
- * Starting from version 1.1, if a {@link CWidgetFactory widget factory} is enabled,
- * this method will use the factory to create the widget, instead.
- * @param {String} className class name (can be in path alias format)
- * @param {Array} properties initial property values
- * @returns {Yii.CWidget} the fully initialized widget instance.
- */
- Yii.CBaseController.prototype.createWidget = function (className, properties) {
- var widget;
- if (properties === undefined) {
- properties = [];
- }
- widget=Yii.app().getWidgetFactory().createWidget(this,className,properties);
-
- widget.init();
- return widget;
- };
- /**
- * Creates a widget and executes it.
- * @param {String} className the widget class name or class in dot syntax (e.g. application.widgets.MyWidget)
- * @param {Array} properties list of initial property values for the widget (Property Name => Property Value)
- * @param {Boolean} captureOutput whether to capture the output of the widget. If true, the method will capture
- * and return the output generated by the widget. If false, the output will be directly sent for display
- * and the widget object will be returned. This parameter is available since version 1.1.2.
- * @returns {Mixed} the widget instance when $captureOutput is false, or the widget output when $captureOutput is true.
- */
- Yii.CBaseController.prototype.widget = function (className, properties, captureOutput) {
- var widget;
- if (properties === undefined) {
- properties = [];
- }
- widget=this.createWidget(className,properties);
- return(widget.run());
-
- };
- /**
- * Creates a widget and executes it.
- * This method is similar to {@link widget()} except that it is expecting
- * a {@link endWidget()} call to end the execution.
- * @param {String} className the widget class name or class in dot syntax (e.g. application.widgets.MyWidget)
- * @param {Array} properties list of initial property values for the widget (Property Name => Property Value)
- * @returns {Yii.CWidget} the widget created to run
- * @see endWidget
- */
- Yii.CBaseController.prototype.beginWidget = function (className, properties) {
- var widget;
- if (properties === undefined) {
- properties = [];
- }
- widget=this.createWidget(className,properties);
-
- this._widgetStack.push(widget);
- return widget;
- };
- /**
- * Ends the execution of the named widget.
- * This method is used together with {@link beginWidget()}.
- * @param {String} id optional tag identifying the method call for debugging purpose.
- * @returns {Yii.CWidget} the widget just ended running
- * @throws {Yii.CException} if an extra endWidget call is made
- * @see beginWidget
- */
- Yii.CBaseController.prototype.endWidget = function (id) {
- var widget;
- if (id === undefined) {
- id = '';
- }
- if((widget=php.array_pop(this._widgetStack))!==null)
- {
- widget.run();
- return widget;
- }
- else {
- throw new Yii.CException(Yii.t('yii','{controller} has an extra endWidget({id}) call in its view.',
- {'{controller}':php.get_class(this),'{id}':id}));
- }
- };
- /**
- * Begins recording a clip.
- * This method is a shortcut to beginning {@link CClipWidget}.
- * @param {String} id the clip ID.
- * @param {Array} properties initial property values for {@link CClipWidget}.
- */
- Yii.CBaseController.prototype.beginClip = function (id, properties) {
- if (properties === undefined) {
- properties = [];
- }
- properties.id=id;
- this.beginWidget('CClipWidget',properties);
- };
- /**
- * Ends recording a clip.
- * This method is an alias to {@link endWidget}.
- */
- Yii.CBaseController.prototype.endClip = function () {
- this.endWidget('CClipWidget');
- };
- /**
- * Begins fragment caching.
- * This method will display cached content if it is availabe.
- * If not, it will start caching and would expect a {@link endCache()}
- * call to end the cache and save the content into cache.
- * A typical usage of fragment caching is as follows,
- * <pre>
- * if(this.beginCache(id))
- * {
- * // ...generate content here
- * this.endCache();
- * }
- * </pre>
- * @param {String} id a unique ID identifying the fragment to be cached.
- * @param {Array} properties initial property values for {@link COutputCache}.
- * @returns {Boolean} whether we need to generate content for caching. False if cached version is available.
- * @see endCache
- */
- Yii.CBaseController.prototype.beginCache = function (id, properties) {
- var cache;
- if (properties === undefined) {
- properties = [];
- }
- properties.id=id;
- cache=this.beginWidget('COutputCache',properties);
- if(cache.getIsContentCached())
- {
- this.endCache();
- return false;
- }
- else {
- return true;
- }
- };
- /**
- * Ends fragment caching.
- * This is an alias to {@link endWidget}.
- * @see beginCache
- */
- Yii.CBaseController.prototype.endCache = function () {
- this.endWidget('COutputCache');
- };
- /**
- * Begins the rendering of content that is to be decorated by the specified view.
- * @param {Mixed} view the name of the view that will be used to decorate the content. The actual view script
- * is resolved via {@link getViewFile}. If this parameter is null (default),
- * the default layout will be used as the decorative view.
- * Note that if the current controller does not belong to
- * any module, the default layout refers to the application's {@link CWebApplication::layout default layout};
- * If the controller belongs to a module, the default layout refers to the module's
- * {@link CWebModule::layout default layout}.
- * @param {Object} data the variables (name=>value) to be extracted and made available in the decorative view.
- * This parameter has been available since version 1.0.4
- * @see beginContent
- * @see CContentDecorator
- */
- Yii.CBaseController.prototype.beginContent = function (view, data) {
- if (view === undefined) {
- view = null;
- }
- if (data === undefined) {
- data = {};
- }
- this.beginWidget('CContentDecorator',{'view':view, 'data':data});
- };
- /**
- * Ends the rendering of content.
- * @see beginContent
- */
- Yii.CBaseController.prototype.endContent = function () {
- this.endWidget('CContentDecorator');
- }/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CWidget is the base class for widgets.
- *
- * A widget is a self-contained component that may generate presentation
- * based on model data. It can be viewed as a micro-controller that embeds
- * into the controller-managed views.
- *
- * Compared with {@link CController controller}, a widget has neither actions nor filters.
- *
- * Usage is described at {@link CBaseController} and {@link CBaseController::widget}.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CWidget.php 3097 2011-03-17 20:01:03Z qiang.xue $
- * @package system.web.widgets
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CBaseController
- */
- Yii.CWidget = function CWidget() {
- };
- Yii.CWidget.prototype = new Yii.CBaseController();
- Yii.CWidget.prototype.constructor = Yii.CWidget;
- /**
- * @var {String} the prefix to the IDs of the {@link actions}.
- * When a widget is declared an action provider in {@link CController::actions},
- * a prefix can be specified to differentiate its action IDs from others.
- * The same prefix should then also be used to configure this property
- * when the widget is used in a view of the controller.
- * @since 1.0.1
- */
- Yii.CWidget.prototype.actionPrefix = null;
- /**
- * @var {Mixed} the name of the skin to be used by this widget. Defaults to 'default'.
- * If this is set as false, no skin will be applied to this widget.
- * @see CWidgetFactory
- * @since 1.1
- */
- Yii.CWidget.prototype.skin = 'default';
- /**
- * @var {Object} view paths for different types of widgets
- */
- Yii.CWidget.prototype._viewPaths = {};
- /**
- * @var {Integer} the counter for generating implicit IDs.
- */
- Yii.CWidget.prototype._counter = 0;
- /**
- * @var {String} id of the widget.
- */
- Yii.CWidget.prototype._id = null;
- /**
- * @var {Yii.CBaseController} owner/creator of this widget. It could be either a widget or a controller.
- */
- Yii.CWidget.prototype._owner = null;
- /**
- * Returns a list of actions that are used by this widget.
- * The structure of this method's return value is similar to
- * that returned by {@link CController::actions}.
- *
- * When a widget uses several actions, you can declare these actions using
- * this method. The widget will then become an action provider, and the actions
- * can be easily imported into a controller.
- *
- * Note, when creating URLs referring to the actions listed in this method,
- * make sure the action IDs are prefixed with {@link actionPrefix}.
- *
- * @see actionPrefix
- * @see CController::actions
- * @since 1.0.1
- */
- Yii.CWidget.prototype.actions = function () {
- return [];
- };
- /**
- * Constructor.
- * @param {Yii.CBaseController} owner owner/creator of this widget. It could be either a widget or a controller.
- */
- Yii.CWidget.prototype.construct = function (owner) {
- if (owner === undefined) {
- owner = null;
- }
- this._owner=owner===null?Yii.app().getController():owner;
- };
- /**
- * Returns the owner/creator of this widget.
- * @returns {Yii.CBaseController} owner/creator of this widget. It could be either a widget or a controller.
- */
- Yii.CWidget.prototype.getOwner = function () {
- return this._owner;
- };
- /**
- * Returns the ID of the widget or generates a new one if requested.
- * @param {Boolean} autoGenerate whether to generate an ID if it is not set previously
- * @returns {String} id of the widget.
- */
- Yii.CWidget.prototype.getId = function (autoGenerate) {
- var _counter;
- if (autoGenerate === undefined) {
- autoGenerate = true;
- }
- if(this._id!==null) {
- return this._id;
- }
- else if(autoGenerate) {
- return (this._id='yw'+Yii.CWidget.prototype._counter++);
- }
- };
- /**
- * Sets the ID of the widget.
- * @param {String} value id of the widget.
- */
- Yii.CWidget.prototype.setId = function (value) {
- this._id=value;
- };
- /**
- * Returns the controller that this widget belongs to.
- * @returns {Yii.CController} the controller that this widget belongs to.
- */
- Yii.CWidget.prototype.getController = function () {
- if(this._owner instanceof Yii.CController) {
- return this._owner;
- }
- else {
- return Yii.app().getController();
- }
- };
- /**
- * Initializes the widget.
- * This method is called by {@link CBaseController::createWidget}
- * and {@link CBaseController::beginWidget} after the widget's
- * properties have been initialized.
- */
- Yii.CWidget.prototype.init = function () {
- };
- /**
- * Executes the widget.
- * This method is called by {@link CBaseController::endWidget}.
- */
- Yii.CWidget.prototype.run = function () {
- };
- /**
- * Returns the directory containing the view files for this widget.
- * The default implementation returns the 'views' subdirectory of the directory containing the widget class file.
- * If $checkTheme is set true, the directory "ThemeID/views/ClassName" will be returned when it exists.
- * @param {Boolean} checkTheme whether to check if the theme contains a view path for the widget.
- * @returns {String} the directory containing the view files for this widget.
- */
- Yii.CWidget.prototype.getViewPath = function (checkTheme) {
- var className, _viewPaths, theme, path, viewFolder, pathParts;
- if (checkTheme === undefined) {
- checkTheme = false;
- }
- className=php.get_class(this);
- if(Yii.CWidget.prototype._viewPaths[className] !== undefined) {
- return Yii.CWidget.prototype._viewPaths[className];
- }
- else
- {
- if(checkTheme && (theme=Yii.app().getTheme())!==null) {
- path=theme.getViewPath()+"/";
- path+=className;
- return (Yii.CWidget.prototype._viewPaths[className]=path);
- }
-
- viewFolder = php.rtrim(Yii.app().getBasePath(),"/") + '/views/widgets/';
- return (Yii.CWidget.prototype._viewPaths[className]=viewFolder + className);
- }
- };
- /**
- * Looks for the view script file according to the view name.
- * This method will look for the view under the widget's {@link getViewPath viewPath}.
- * The view script file is named as "ViewName.php". A localized view file
- * may be returned if internationalization is needed. See {@link CApplication::findLocalizedFile}
- * for more details.
- * Since version 1.0.2, the view name can also refer to a path alias
- * if it contains dot characters.
- * @param {String} viewName name of the view (without file extension)
- * @returns {String} the view file path. False if the view file does not exist
- * @see CApplication::findLocalizedFile
- */
- Yii.CWidget.prototype.getViewFile = function (viewName) {
- var renderer, extension, viewFile;
- if((renderer=Yii.app().getViewRenderer())!==undefined) {
- extension=renderer.fileExtension;
- }
- else {
- extension='.js';
- }
- if(php.strpos(viewName,'.')) { // a path alias
- viewFile=Yii.getPathOfAlias(viewName);
- }
- else {
- viewFile=this.getViewPath(true)+'/'+viewName;
- return Yii.app().findLocalizedFile(viewFile+extension);
-
- }
- if(is_file(viewFile+extension)) {
- return Yii.app().findLocalizedFile(viewFile+extension);
- }
- else if(extension!=='.js' && is_file(viewFile+'.js')) {
- return Yii.app().findLocalizedFile(viewFile+'.js');
- }
- else {
- return false;
- }
- };
- /**
- * Renders a view.
- *
- * The named view refers to a PHP script (resolved via {@link getViewFile})
- * that is included by this method. If $data is an associative array,
- * it will be extracted as PHP variables and made available to the script.
- *
- * @param {String} view name of the view to be rendered. See {@link getViewFile} for details
- * about how the view script is resolved.
- * @param {Array} data data to be extracted into PHP variables and made available to the view script
- * @param {Boolean} returnVar whether the rendering result should be returned instead of being displayed to end users
- * @returns {String} the rendering result. Null if the rendering result is not required.
- * @throws {Yii.CException} if the view does not exist
- * @see getViewFile
- */
- Yii.CWidget.prototype.render = function (view, data, returnVar) {
- var viewFile;
- if (data === undefined) {
- data = null;
- }
- if (returnVar === undefined) {
- returnVar = false;
- }
- if((viewFile=this.getViewFile(view))!==false) {
- return this.renderFile(viewFile,data,returnVar);
- }
- else {
- throw new Yii.CException(Yii.t('yii','{widget} cannot find the view "{view}".',
- {'{widget}':php.get_class(this), '{view}':view}));
- }
- }/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CLogRoute is the base class for all log route classes.
- *
- * A log route object retrieves log messages from a logger and sends it
- * somewhere, such as files, emails.
- * The messages being retrieved may be filtered first before being sent
- * to the destination. The filters include log level filter and log category filter.
- *
- * To specify level filter, set {@link levels} property,
- * which takes a string of comma-separated desired level names (e.g. 'Error, Debug').
- * To specify category filter, set {@link categories} property,
- * which takes a string of comma-separated desired category names (e.g. 'System.Web, System.IO').
- *
- * Level filter and category filter are combinational, i.e., only messages
- * satisfying both filter conditions will they be returned.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CLogRoute.php 3001 2011-02-24 16:42:44Z alexander.makarow $
- * @package system.logging
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CComponent
- */
- Yii.CLogRoute = function CLogRoute () {
- };
- Yii.CLogRoute.prototype = new Yii.CComponent();
- Yii.CLogRoute.prototype.constructor = Yii.CLogRoute;
- /**
- * @var {Boolean} whether to enable this log route. Defaults to true.
- * @since 1.0.7
- */
- Yii.CLogRoute.prototype.enabled = true;
- /**
- * @var {String} list of levels separated by comma or space. Defaults to empty, meaning all levels.
- */
- Yii.CLogRoute.prototype.levels = '';
- /**
- * @var {String} list of categories separated by comma or space. Defaults to empty, meaning all categories.
- */
- Yii.CLogRoute.prototype.categories = '';
- /**
- * @var {Mixed} the additional filter (eg {@link CLogFilter}) that can be applied to the log messages.
- * The value of this property will be passed to {@link Yii::createComponent} to create
- * a log filter object. As a result, this can be either a string representing the
- * filter class name or an array representing the filter configuration.
- * In general, the log filter class should be {@link CLogFilter} or a child class of it.
- * Defaults to null, meaning no filter will be used.
- * @since 1.0.6
- */
- Yii.CLogRoute.prototype.filter = null;
- /**
- * @var {Array} the logs that are collected so far by this log route.
- * @since 1.1.0
- */
- Yii.CLogRoute.prototype.logs = null;
- /**
- * Initializes the route.
- * This method is invoked after the route is created by the route manager.
- */
- Yii.CLogRoute.prototype.init = function () {
- };
- /**
- * Formats a log message given different fields.
- * @param {String} message message content
- * @param {Integer} level message level
- * @param {String} category message category
- * @param {Integer} time timestamp
- * @returns {String} formatted message
- */
- Yii.CLogRoute.prototype.formatLogMessage = function (message, level, category, time) {
- return php.date('Y/m/d H:i:s',time)+" [" + level + "] [" + category + "] " + message + "\n";
- };
- /**
- * Retrieves filtered log messages from logger for further processing.
- * @param {Yii.CLogger} logger logger instance
- * @param {Boolean} processLogs whether to process the logs after they are collected from the logger
- */
- Yii.CLogRoute.prototype.collectLogs = function (logger, processLogs) {
- var logs;
-
- if (processLogs === undefined) {
- processLogs = false;
- }
-
- logs=logger.getLogs(this.levels,this.categories);
- this.logs=php.empty(this.logs) ? logs : php.array_merge(this.logs,logs);
- if(processLogs && !php.empty(this.logs)) {
- if(this.filter!==null) {
- Yii.createComponent(this.filter).filter(this.logs);
- }
- this.processLogs(this.logs);
- }
- };
- /**
- * Processes log messages and sends them to specific destination.
- * Derived child classes must implement this method.
- * @param {Array} logs list of messages. Each array elements represents one message
- * with the following structure:
- * array(
- * [0] => message (string)
- * [1] => level (string)
- * [2] => category (string)
- * [3] => timestamp (float, obtained by microtime(true));
- */
- Yii.CLogRoute.prototype.processLogs = function (logs) {
- };/*global Yii, php, $, jQuery, console, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CWebLogRoute shows the log content in Web page.
- *
- * The log content can appear either at the end of the current Web page
- * or in FireBug console window (if {@link showInFireBug} is set true).
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CWebLogRoute.php 3001 2011-02-24 16:42:44Z alexander.makarow $
- * @package system.logging
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CLogRoute
- */
- Yii.CWebLogRoute = function CWebLogRoute () {
- };
- Yii.CWebLogRoute.prototype = new Yii.CLogRoute();
- Yii.CWebLogRoute.prototype.constructor = Yii.CWebLogRoute;
- /**
- * @var {Boolean} whether the log should be displayed in FireBug instead of browser window. Defaults to false.
- */
- Yii.CWebLogRoute.prototype.showInFireBug = false;
- /**
- * @var {Boolean} whether the log should be ignored in FireBug for ajax calls. Defaults to true.
- * This option should be used carefully, because an ajax call returns all output as a result data.
- * For example if the ajax call expects a json type result any output from the logger will cause ajax call to fail.
- */
- Yii.CWebLogRoute.prototype.ignoreAjaxInFireBug = true;
- /**
- * Displays the log messages.
- * @param {Array} logs list of log messages
- */
- Yii.CWebLogRoute.prototype.processLogs = function (logs) {
- var logView = [], i, limit, log;
- limit = logs.length;
- for (i = 0; i < limit; i++) {
- log = logs[i];
- logView.push({
- 'time': php.date('H:i:s.',log[3]) + php.sprintf('%06d',Number((log[3]-Number(log[3]))*1000000)),
- 'level': log[1],
- 'category': log[2],
- 'message': log[0]
- });
- }
- if (this.showInFireBug) {
- if (console.group !== undefined) {
- console.group("Application Log");
- }
- Yii.forEach(logView, function (index, log) {
- var func;
- if (log[1] === Yii.CLogger.prototype.LEVEL_WARNING) {
- func = "warn";
- }
- else if (log[2] === Yii.CLogger.prototype.LEVEL_ERROR) {
- func = "error";
- }
- else {
- func = "log";
- }
- if (console[func] === undefined) {
- func = "log";
- }
- console[func]("[" + log.time + "] [" + log.level + "] [" + log.category + "] " + log.message);
- });
- if (console.group !== undefined) {
- console.groupEnd();
- }
- }
- else {
- this.render('log',logView);
- }
- };
- /**
- * Renders the view.
- * @param {String} view the view name (file name without extension). The file is assumed to be located under framework/data/views.
- * @param {Array} data data to be passed to the view
- */
- Yii.CWebLogRoute.prototype.render = function (view, data) {
- var app, isAjax, viewFile;
-
- app=Yii.app();
- isAjax=app.getRequest().getIsAjaxRequest();
- if(this.showInFireBug) {
- if(isAjax && this.ignoreAjaxInFireBug) {
- return;
- }
- view+='-firebug';
- }
- else if(!(app instanceof Yii.CWebApplication) || isAjax) {
- return;
- }
- viewFile='system.views.'+view;
- jQuery("body").append(Yii.CController.prototype.renderPartial(viewFile, {data: data},true));
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CView is a base class for views
- *
- * @package system.web
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CComponent
- */
- Yii.CView = function CView (config) {
- if (config !== false) {
- this.template = null;
- this.construct(config);
- }
- };
- Yii.CView.prototype = new Yii.CComponent();
- Yii.CView.prototype.constructor = Yii.CView;
- /**
- * Holds a list of registered views
- */
- Yii.CView.prototype._views = {};
-
- /**
- * Holds a list of cached templates
- * @var Object
- */
- Yii.CView.prototype._templates = {};
- /**
- * The content of the template that should be used to render this view
- * @var String
- */
- Yii.CView.prototype.template = null;
-
- /**
- * The URL of the template to use for this view.
- * @var String
- */
- Yii.CView.prototype.templateURL = null;
-
- /**
- * The layout view to use when rendering, if none specified
- * the default layout will be used.
- * @var Yii.CView
- */
- Yii.CView.prototype.layout = null;
-
- /**
- * jQuery events to delegate for this view.
- * Array should be of the following format:
- * <pre>
- * [
- * ['#selector a.someLink', 'click', function (e) { alert("clicked!")}],
- * ['#selector form', 'submit', function (e) { alert('Submitted!'); e.preventDefault(); }]
- * ]
- * </pre>
- * These events will be bound to their selectors when the view is rendered
- * @var Array
- */
- Yii.CView.prototype.delegates = [];
- /**
- * Registers a view that can be rendered later
- * @param {String} alias The alias for this view so it can be retrieved later
- * @param {Object} config An object that will be used as a configuration for a new CView
- */
- Yii.CView.prototype.registerView = function (alias, config) {
- var url;
- if (alias.indexOf("/") === -1) {
- url = Yii.getPathOfAlias(alias) + ".js";
- }
- else {
- url = alias;
- }
- Yii.CView.prototype._views[url] = config;
- };
-
- /**
- * Loads a particular view and executes the callback
- * @param {String} alias The alias of the view to load
- * @param {Function} callback The callback to execute, it will receive the loaded view as first parameter
- */
- Yii.CView.prototype.load = function (alias, callback) {
- var config, view, className, url;
- if (alias.indexOf("/") === -1) {
- url = Yii.getPathOfAlias(alias) + ".js";
- }
- else {
- url = alias;
- }
- config = Yii.CView.prototype._views[url];
-
- if (config === undefined) {
- // load the view
-
- Yii.include(url, true, function() {
- config = Yii.CView.prototype._views[url];
-
- if (config === undefined) {
- throw new Yii.CHttpException(404, "No such view: " + url);
- }
- if (config['class'] === undefined) {
- className = "CView";
- }
- else {
- className = config['class'];
- delete config['class'];
- }
- return callback(new Yii[className](config));
- });
- }
- else {
- if (config['class'] === undefined) {
- className = "CView";
- }
- else {
- className = config['class'];
- delete config['class'];
- }
- return callback(new Yii[className](config));
- }
- }
-
- /**
- * Constructs the view and applies the given configuration
- */
- Yii.CView.prototype.construct = function (config) {
- var self = this;
- if (config === undefined) {
- return;
- }
- Yii.forEach(config, function (key, value) {
- self[key] = value;
- });
- }
- /**
- * Renders the view wrapped in the layout
- * @param {Function} callback The function to execute after the view has been rendered
- */
- Yii.CView.prototype.render = function (callback) {
- var func, self = this;
- if (this.layout === null) {
- this.renderPartial(callback);
- }
- else {
- this.load(this.layout, function(layout) {
- func = function(html) {
- layout.content = html;
- layout.render(callback);
- }
- self.renderPartial(func);
- });
-
- }
- };
-
- /**
- * Renders the view
- * @param {Function} callback The function to execute after the view has been rendered
- */
- Yii.CView.prototype.renderPartial = function (callback) {
- var elements = {}, dependencies = [], stack = [], self = this, output = "", func;
- Yii.forEach(this, function(name, value) {
- if (name.slice(0,1) !== "_") {
- elements[name] = value;
- if (value instanceof Yii.CView) {
- dependencies.push(name);
- }
- }
- });
- Yii.forEach(this.delegates, function(i, item) {
- jQuery("body").undelegate(item[0], item[1]).delegate(item[0], item[1], item[2]);
- });
- func = function() {
- self.getTemplate(function(template) {
- callback(Mustache.to_html(template, self), self);
-
- });
- }
- if (dependencies.length > 0) {
- // can only call this callback when the others have completed.
- stack.push(func);
- Yii.forEach(dependencies, function(i, name) {
- stack.push(function() {
- self[name].renderPartial(function(output, parent) {
- self[name] = output;
- stack.pop()();
- });
- });
-
- });
- return stack.pop()();
- }
- else {
- func();
- }
- };
-
-
- /**
- * Gets the contents of the template
- * @param {Function} callback The function to execute after retrieving the template contents
- * @returns {String} the template contents
- */
- Yii.CView.prototype.getTemplate = function (callback) {
- var self = this, url;
-
- if (this.template === null) {
- url = this.templateURL;
- if (url.indexOf("/") === -1 && url.indexOf(".") !== -1) {
- url = Yii.getPathOfAlias(url) + ".tpl";
- }
- if (this._templates[url] !== undefined) {
- this.template = this._templates[url];
- callback(this.template, this);
- }
- else {
- jQuery.ajax(url, {
- success: function(data) {
- self._templates[url] = data;
- self.template = data;
- callback(self.template, self);
- },
- error: function (xhr) {
- self._template = "ERROR: " + xhr.responseText;
- callback(self.template, self);
- }
-
- });
- }
- }
- else {
- callback(this.template, this);
- }
- return this.template;
- };
-
- /**
- * Sets the contents of the template
- * @param {String} value The template contents
- */
- Yii.CView.prototype.setTemplate = function (value) {
- this.template = value;
- }
- /*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CApplication is the base class for all application classes.
- *
- * An application serves as the global context that the user request
- * is being processed. It manages a set of application components that
- * provide specific functionalities to the whole application.
- *
- * The core application components provided by CApplication are the following:
- * <ul>
- * <li>{@link getErrorHandler errorHandler}: handles JavaScript errors and
- * uncaught exceptions. This application component is dynamically loaded when needed.</li>
- * <li>{@link getSecurityManager securityManager}: provides security-related
- * services, such as hashing, encryption. This application component is dynamically
- * loaded when needed.</li>
- * <li>{@link getStatePersister statePersister}: provides global state
- * persistence method. This application component is dynamically loaded when needed.</li>
- * <li>{@link getCache cache}: provides caching feature. This application component is
- * disabled by default.</li>
- * <li>{@link getMessages messages}: provides the message source for translating
- * application messages. This application component is dynamically loaded when needed.</li>
- * <li>{@link getCoreMessages coreMessages}: provides the message source for translating
- * Yii framework messages. This application component is dynamically loaded when needed.</li>
- * </ul>
- *
- * CApplication will undergo the following lifecycles when processing a user request:
- * <ol>
- * <li>load application configuration;</li>
- * <li>set up class autoloader and error handling;</li>
- * <li>load static application components;</li>
- * <li>{@link onBeginRequest}: preprocess the user request;</li>
- * <li>{@link processRequest}: process the user request;</li>
- * <li>{@link onEndRequest}: postprocess the user request;</li>
- * </ol>
- *
- * Starting from lifecycle 3, if a JavaScript error or an uncaught exception occurs,
- * the application will switch to its error handling logic and jump to step 6 afterwards.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CApplication.php 3001 2011-02-24 16:42:44Z alexander.makarow $
- * @package system.base
- * @since 1.0
- *
- * @property string $basePath Returns the root path of the application.
- * @property CCache $cache Returns the cache component.
- * @property CPhpMessageSource $coreMessages Returns the core message translations.
- * @property CDateFormatter $dateFormatter Returns the locale-dependent date formatter.
- * @property CDbConnection $db Returns the database connection component.
- * @property CErrorHandler $errorHandler Returns the error handler component.
- * @property string $extensionPath Returns the root directory that holds all third-party extensions.
- * @property string $id Returns the unique identifier for the application.
- * @property string $language Returns the language that the user is using and the application should be targeted to.
- * @property CLocale $locale Returns the locale instance.
- * @property string $localeDataPath Returns the directory that contains the locale data.
- * @property CMessageSource $messages Returns the application message translations component.
- * @property CNumberFormatter $numberFormatter The locale-dependent number formatter.
- * @property CHttpRequest $request Returns the request component.
- * @property string $runtimePath Returns the directory that stores runtime files.
- * @property CSecurityManager $securityManager Returns the security manager component.
- * @property CStatePersister $statePersister Returns the state persister component.
- * @property string $timeZone Returns the time zone used by this application.
- * @property CUrlManager $urlManager Returns the URL manager component.
- * @author Charles Pick
- * @class
- * @extends Yii.CModule
- */
- Yii.CApplication = function CApplication (config) {
- if (config !== false) {
- this.construct(config);
- }
- };
- Yii.CApplication.prototype = new Yii.CModule(false);
- Yii.CApplication.prototype.constructor = Yii.CApplication;
- /**
- * @var {String} the application name. Defaults to 'My Application'.
- */
- Yii.CApplication.prototype.name = 'My Application';
- /**
- * @var {String} the charset currently used for the application. Defaults to 'UTF-8'.
- */
- Yii.CApplication.prototype.charset = 'UTF-8';
- /**
- * @var {String} the language that the application is written in. This mainly refers to
- * the language that the messages and view files are in. Defaults to 'en_us' (US English).
- */
- Yii.CApplication.prototype.sourceLanguage = 'en_us';
- Yii.CApplication.prototype._id = null;
- Yii.CApplication.prototype._basePath = null;
- Yii.CApplication.prototype._runtimePath = null;
- Yii.CApplication.prototype._extensionPath = null;
- Yii.CApplication.prototype._globalState = null;
- Yii.CApplication.prototype._stateChanged = null;
- Yii.CApplication.prototype._ended = false;
- Yii.CApplication.prototype._language = null;
- Yii.CApplication.prototype._timezone = null;
- /**
- * Processes the request.
- * This is the place where the actual request processing work is done.
- * Derived classes should override this method.
- */
- Yii.CApplication.prototype.processRequest = function () {
- };
- /**
- * Constructor.
- * @param {Mixed} config application configuration.
- * If a string, it is treated as the path of the file that contains the configuration;
- * If an array, it is the actual configuration information.
- * Please make sure you specify the {@link getBasePath basePath} property in the configuration,
- * which should point to the directory containing all application logic, template and data.
- * If not, the directory will be defaulted to 'protected'.
- */
- Yii.CApplication.prototype.construct = function (config) {
- if (config === undefined) {
- config = {};
- }
- Yii.setApplication(this);
-
- // set basePath at early as possible to avoid trouble
-
- if(config.basePath !== undefined) {
- this.setBasePath(config.basePath);
- delete config.basePath;
- }
- else {
- this.setBasePath('protected');
- }
- Yii.setPathOfAlias('application',this.getBasePath());
- Yii.setPathOfAlias('webroot',location.protocol + "//" + location.hostname + "/");
- Yii.setPathOfAlias('ext',this.getBasePath()+'/'+'extensions');
- this.preinit();
-
- this.initSystemHandlers();
- this.registerCoreComponents();
- this.configure(config);
- this.attachBehaviors(this.behaviors);
- this.preloadComponents();
- this.init();
- };
- /**
- * Runs the application.
- * This method loads static application components. Derived classes usually overrides this
- * method to do more application-specific tasks.
- * Remember to call the parent implementation so that static application components are loaded.
- */
- Yii.CApplication.prototype.run = function () {
- try {
- if(this.hasEventHandler('onBeginRequest')) {
- this.onBeginRequest(new Yii.CEvent(this));
- }
- Yii.beginProfile("Request");
- this.processRequest();
- Yii.endProfile("Request");
- if(this.hasEventHandler('onEndRequest')) {
- this.onEndRequest(new Yii.CEvent(this));
- }
- }
- catch (e) {
- if (e instanceof TypeError) {
- this.displayError("TypeError",e);
- }
- else if (e instanceof Yii.CException) {
- this.displayException(e);
- }
- else {
- this.displayError("Error",e);
- }
- }
- };
- /**
- * Terminates the application.
- * This method replaces JavaScript's exit() function by calling
- * {@link onEndRequest} before exiting.
- * @param {Integer} status exit status (value 0 means normal exit while other values mean abnormal exit).
- * @param {Boolean} exit whether to exit the current request. This parameter has been available since version 1.1.5.
- * It defaults to true, meaning the JavaScript's exit() function will be called at the end of this method.
- */
- Yii.CApplication.prototype.end = function (status, exit) {
- if (status === undefined) {
- status = 0;
- }
- if (exit === undefined) {
- exit = true;
- }
- if(this.hasEventHandler('onEndRequest')) {
- this.onEndRequest(new Yii.CEvent(this));
- }
- if(exit) {
- exit(status);
- }
- };
- /**
- * Raised right BEFORE the application processes the request.
- * @param {Yii.CEvent} event the event parameter
- */
- Yii.CApplication.prototype.onBeginRequest = function (event) {
- this.raiseEvent('onBeginRequest',event);
- };
- /**
- * Raised right AFTER the application processes the request.
- * @param {Yii.CEvent} event the event parameter
- */
- Yii.CApplication.prototype.onEndRequest = function (event) {
- if(!this._ended) {
- this._ended=true;
- this.raiseEvent('onEndRequest',event);
- }
- };
- /**
- * Returns the unique identifier for the application.
- * @returns {String} the unique identifier for the application.
- */
- Yii.CApplication.prototype.getId = function () {
- if(this._id!==null) {
- return this._id;
- }
- else {
- return (this._id=php.sprintf('%x',php.crc32(this.getBasePath()+this.name)));
- }
- };
- /**
- * Sets the unique identifier for the application.
- * @param {String} id the unique identifier for the application.
- */
- Yii.CApplication.prototype.setId = function (id) {
- this._id=id;
- };
- /**
- * Returns the root path of the application.
- * @returns {String} the root directory of the application. Defaults to 'protected'.
- */
- Yii.CApplication.prototype.getBasePath = function () {
- return this._basePath;
- };
- /**
- * Sets the root directory of the application.
- * This method can only be invoked at the begin of the constructor.
- * @param {String} path the root directory of the application.
- */
- Yii.CApplication.prototype.setBasePath = function (path) {
- this._basePath = path;
- };
- /**
- * Returns the directory that stores runtime files.
- * @returns {String} the directory that stores runtime files. Defaults to 'protected/runtime'.
- */
- Yii.CApplication.prototype.getRuntimePath = function () {
- if(this._runtimePath!==null) {
- return this._runtimePath;
- }
- else
- {
- this.setRuntimePath(this.getBasePath()+"/runtime");
- return this._runtimePath;
- }
- };
- /**
- * Sets the directory that stores runtime files.
- * @param {String} path the directory that stores runtime files.
- */
- Yii.CApplication.prototype.setRuntimePath = function (path) {
- this._runtimePath= path;
- };
- /**
- * Returns the root directory that holds all third-party extensions.
- * @returns {String} the directory that contains all extensions. Defaults to the 'extensions' directory under 'protected'.
- */
- Yii.CApplication.prototype.getExtensionPath = function () {
- return Yii.getPathOfAlias('ext');
- };
- /**
- * Sets the root directory that holds all third-party extensions.
- * @param {String} path the directory that contains all third-party extensions.
- */
- Yii.CApplication.prototype.setExtensionPath = function (path) {
- Yii.setPathOfAlias('ext',path);
- };
- /**
- * Returns the language that the user is using and the application should be targeted to.
- * @returns {String} the language that the user is using and the application should be targeted to.
- * Defaults to the {@link sourceLanguage source language}.
- */
- Yii.CApplication.prototype.getLanguage = function () {
- return this._language===null ? this.sourceLanguage : this._language;
- };
- /**
- * Specifies which language the application is targeted to.
- *
- * This is the language that the application displays to end users.
- * If set null, it uses the {@link sourceLanguage source language}.
- *
- * Unless your application needs to support multiple languages, you should always
- * set this language to null to maximize the application's performance.
- * @param {String} language the user language (e.g. 'en_US', 'zh_CN').
- * If it is null, the {@link sourceLanguage} will be used.
- */
- Yii.CApplication.prototype.setLanguage = function (language) {
- this._language=language;
- };
- /**
- * Returns the time zone used by this application.
- * @returns {String} the time zone used by this application.
- * @see http://php.net/manual/en/function.date-default-timezone-get.php
- * @since 1.0.9
- */
- Yii.CApplication.prototype.getTimeZone = function () {
- if (this._timezone === null) {
- this._timezone = jzTimezoneDetector.determine_timezone().timezone.olson_tz;
- }
- return this._timezone;
- };
- /**
- * Sets the time zone used by this application.
- * This is a simple wrapper of JavaScript function date_default_timezone_set().
- * @param {String} value the time zone used by this application.
- * @see http://php.net/manual/en/function.date-default-timezone-set.php
- * @since 1.0.9
- */
- Yii.CApplication.prototype.setTimeZone = function (value) {
- this._timezone = value;
- };
- /**
- * Returns the localized version of a specified file.
- *
- * The searching is based on the specified language code. In particular,
- * a file with the same name will be looked for under the subdirectory
- * named as the locale ID. For example, given the file "path/to/view.php"
- * and locale ID "zh_cn", the localized file will be looked for as
- * "path/to/zh_cn/view.php". If the file is not found, the original file
- * will be returned.
- *
- * For consistency, it is recommended that the locale ID is given
- * in lower case and in the format of LanguageID_RegionID (e.g. "en_us").
- *
- * @param {String} srcFile the original file
- * @param {String} srcLanguage the language that the original file is in. If null, the application {@link sourceLanguage source language} is used.
- * @param {String} language the desired language that the file should be localized to. If null, the {@link getLanguage application language} will be used.
- * @returns {String} the matching localized file. The original file is returned if no localized version is found
- * or if source language is the same as the desired language.
- */
- Yii.CApplication.prototype.findLocalizedFile = function (srcFile, srcLanguage, language) {
- var desiredFile;
- if (srcLanguage === undefined) {
- srcLanguage = null;
- }
- if (language === undefined) {
- language = null;
- }
- if(srcLanguage===null) {
- srcLanguage=this.sourceLanguage;
- }
- if(language===null) {
- language=this.getLanguage();
- }
- if(language===srcLanguage) {
- return srcFile;
- }
-
- // TODO: fix this and determine how to deal with localized files
- return srcFile;
- //desiredFile=php.dirname(srcFile)+DIRECTORY_SEPARATOR+language+DIRECTORY_SEPARATOR+php.basename(srcFile);
- //return is_file(desiredFile) ? desiredFile : srcFile;
- };
- /**
- * Returns the locale instance.
- * @param {String} localeID the locale ID (e.g. en_US). If null, the {@link getLanguage application language ID} will be used.
- * @returns {Yii.CLocale} the locale instance
- */
- Yii.CApplication.prototype.getLocale = function (localeID) {
- if (localeID === undefined) {
- localeID = null;
- }
- return Yii.CLocale.getInstance(localeID===null?this.getLanguage():localeID);
- };
- /**
- * Returns the directory that contains the locale data.
- * @returns {String} the directory that contains the locale data. It defaults to 'framework/i18n/data'.
- * @since 1.1.0
- */
- Yii.CApplication.prototype.getLocaleDataPath = function () {
- var dataPath;
- return Yii.CLocale.dataPath===null ? Yii.getPathOfAlias('system.i18n.data') : Yii.CLocale.dataPath;
- };
- /**
- * Sets the directory that contains the locale data.
- * @param {String} value the directory that contains the locale data.
- * @since 1.1.0
- */
- Yii.CApplication.prototype.setLocaleDataPath = function (value) {
- var dataPath;
- Yii.CLocale.dataPath=value;
- };
- /**
- * @returns {Yii.CNumberFormatter} the locale-dependent number formatter.
- * The current {@link getLocale application locale} will be used.
- */
- Yii.CApplication.prototype.getNumberFormatter = function () {
- return this.getLocale().getNumberFormatter();
- };
- /**
- * Returns the locale-dependent date formatter.
- * @returns {Yii.CDateFormatter} the locale-dependent date formatter.
- * The current {@link getLocale application locale} will be used.
- */
- Yii.CApplication.prototype.getDateFormatter = function () {
- return this.getLocale().getDateFormatter();
- };
- /**
- * Returns the database connection component.
- * @returns {Yii.CDbConnection} the database connection
- */
- Yii.CApplication.prototype.getDb = function () {
- return this.getComponent('db');
- };
- /**
- * Returns the error handler component.
- * @returns {Yii.CErrorHandler} the error handler application component.
- */
- Yii.CApplication.prototype.getErrorHandler = function () {
- return this.getComponent('errorHandler');
- };
- /**
- * Returns the security manager component.
- * @returns {Yii.CSecurityManager} the security manager application component.
- */
- Yii.CApplication.prototype.getSecurityManager = function () {
- return this.getComponent('securityManager');
- };
- /**
- * Returns the state persister component.
- * @returns {Yii.CStatePersister} the state persister application component.
- */
- Yii.CApplication.prototype.getStatePersister = function () {
- return this.getComponent('statePersister');
- };
- /**
- * Returns the cache component.
- * @returns {Yii.CCache} the cache application component. Null if the component is not enabled.
- */
- Yii.CApplication.prototype.getCache = function () {
- return this.getComponent('cache');
- };
- /**
- * Returns the core message translations component.
- * @returns {Yii.CPhpMessageSource} the core message translations
- */
- Yii.CApplication.prototype.getCoreMessages = function () {
- return this.getComponent('coreMessages');
- };
- /**
- * Returns the application message translations component.
- * @returns {Yii.CMessageSource} the application message translations
- */
- Yii.CApplication.prototype.getMessages = function () {
- return this.getComponent('messages');
- };
- /**
- * Returns the request component.
- * @returns {Yii.CHttpRequest} the request component
- */
- Yii.CApplication.prototype.getRequest = function () {
- return this.getComponent('request');
- };
- /**
- * Returns the URL manager component.
- * @returns {Yii.CUrlManager} the URL manager component
- */
- Yii.CApplication.prototype.getUrlManager = function () {
- return this.getComponent('urlManager');
- };
- /**
- * Returns a global value.
- *
- * A global value is one that is persistent across users sessions and requests.
- * @param {String} key the name of the value to be returned
- * @param {Mixed} defaultValue the default value. If the named global value is not found, this will be returned instead.
- * @returns {Mixed} the named global value
- * @see setGlobalState
- */
- Yii.CApplication.prototype.getGlobalState = function (key, defaultValue) {
- if (defaultValue === undefined) {
- defaultValue = null;
- }
- if(this._globalState===null) {
-
- this.loadGlobalState();
- }
- if(this._globalState[key] !== undefined) {
- return this._globalState[key];
- }
- else {
- return defaultValue;
- }
- };
- /**
- * Sets a global value.
- *
- * A global value is one that is persistent across users sessions and requests.
- * Make sure that the value is serializable and unserializable.
- * @param {String} key the name of the value to be saved
- * @param {Mixed} value the global value to be saved. It must be serializable.
- * @param {Mixed} defaultValue the default value. If the named global value is the same as this value, it will be cleared from the current storage.
- * @see getGlobalState
- */
- Yii.CApplication.prototype.setGlobalState = function (key, value, defaultValue) {
- var changed;
- if (defaultValue === undefined) {
- defaultValue = null;
- }
- if(this._globalState===null) {
- this.loadGlobalState();
- }
- changed=this._stateChanged;
- if(value===defaultValue) {
- if(this._globalState[key] !== undefined) {
- delete this._globalState[key];
- this._stateChanged=true;
- }
- }
- else if(this._globalState[key] === undefined || this._globalState[key]!==value) {
- this._globalState[key]=value;
- this._stateChanged=true;
- }
- if(this._stateChanged!==changed) {
- this.saveGlobalState();
- }
- };
- /**
- * Clears a global value.
- *
- * The value cleared will no longer be available in this request and the following requests.
- * @param {String} key the name of the value to be cleared
- */
- Yii.CApplication.prototype.clearGlobalState = function (key) {
- this.setGlobalState(key,true,true);
- };
- /**
- * Loads the global state data from persistent storage.
- * @see getStatePersister
- * @throws {Yii.CException} if the state persister is not available
- */
- Yii.CApplication.prototype.loadGlobalState = function () {
- var persister;
- persister=this.getStatePersister();
- if((this._globalState=persister.load())===null) {
- this._globalState={};
- }
- this._stateChanged=false;
- };
- /**
- * Saves the global state data into persistent storage.
- * @see getStatePersister
- * @throws {Yii.CException} if the state persister is not available
- */
- Yii.CApplication.prototype.saveGlobalState = function () {
- if(this._stateChanged) {
- this._stateChanged=false;
- this.getStatePersister().save(this._globalState);
- }
- };
- /**
- * Handles uncaught JavaScript exceptions.
- *
- * This method is implemented as a JavaScript exception handler. It requires
- * that constant YII_ENABLE_EXCEPTION_HANDLER be defined true.
- *
- * This method will first raise an {@link onException} event.
- * If the exception is not handled by any event handler, it will call
- * {@link getErrorHandler errorHandler} to process the exception.
- *
- * The application will be terminated by this method.
- *
- * @param {Exception} exception exception that is not caught
- */
- Yii.CApplication.prototype.handleException = function (exception) {
- var category, message, event, handler, msg;
- // disable error capturing to avoid recursive errors
-
- category='exception.'+php.get_class(exception);
- if(exception instanceof Yii.CHttpException) {
- category+='.'+exception.statusCode;
- }
- message=exception.message;
-
- Yii.log(message,Yii.CLogger.LEVEL_ERROR,category);
- try
- {
- event=new Yii.CExceptionEvent(this,exception);
- this.onException(event);
- if(!event.handled) {
- // try an error handler
- if((handler=this.getErrorHandler())!==null) {
- handler.handle(event);
- }
- else {
- this.displayException(exception);
- }
- }
- }
- catch(e) {
- this.displayException(e);
- }
- try
- {
- this.end(1);
- return;
- }
- catch(e) {
- // use the most primitive way to log error
- msg = php.get_class(e)+': '+e.message+"\n";
- msg += e.getTraceAsString()+"\n";
- msg += "Previous exception:\n";
- msg += php.get_class(exception)+': '+exception.message+"\n";
- msg += exception.getTraceAsString()+"\n";
- console.log(msg);
- return;
- }
- };
- /**
- * Handles JavaScript execution errors such as warnings, notices.
- *
- * This method is implemented as a JavaScript error handler. It requires
- * that constant YII_ENABLE_ERROR_HANDLER be defined true.
- *
- * This method will first raise an {@link onError} event.
- * If the error is not handled by any event handler, it will call
- * {@link getErrorHandler errorHandler} to process the error.
- *
- * The application will be terminated by this method.
- *
- * @param {Integer} code the level of the error raised
- * @param {String} message the error message
- * @param {String} file the filename that the error was raised in
- * @param {Integer} line the line number the error was raised at
- */
- Yii.CApplication.prototype.handleError = function (code, message, file, line) {
- var log = "", trace, t, i, event, handler, msg;
- if(code) {
- log="message (" + file + ":" + line + ")\nStack trace:\n";
- trace=Yii.CException.prototype.stacktrace();
- // skip the first 3 stacks as they do not tell the error position
- if(php.count(trace)>3) {
- trace=php.array_slice(trace,3);
- }
- for (i in trace) {
- if (trace.hasOwnProperty(i)) {
- t = trace[i];
- if(t.file === undefined) {
- t.file='unknown';
- }
- if(t.line === undefined) {
- t.line=0;
- }
- if(t['function'] === undefined) {
- t['function']='unknown';
- }
- log+="#i " + t.file + "(" + t.line + "): ";
- if(t.object !== undefined && (!t.object instanceof Array && t.object !== null && typeof(t.object) === 'object')) {
- log+=php.get_class(t.object)+'.';
- }
- log+= t['function'] + "()\n";
- }
- }
- Yii.log(log, Yii.CLogger.prototype.LEVEL_ERROR, "js");
- try {
- event = new Yii.CErrorEvent(this, code, message, file, line);
- this.onError(event);
- if (!event.handled) {
- // try an error handler
- handler = this.getErrorHandler();
- if (handler !== null) {
- handler.handle(event);
- }
- else {
- this.displayError(code, message, file, line);
- }
- }
- }
- catch (e) {
- this.displayException(e);
- }
-
- try {
- this.end(1);
- }
- catch(e) {
- // use the most primitive way to log error
- msg = php.get_class(e)+': '+e.message+"\n";
- msg += e.getTraceAsString()+"\n";
- msg += "Previous error:\n";
- msg += log + "\n";
- console.log(msg);
- return;
- }
- }
- };
- /**
- * Raised when an uncaught JavaScript exception occurs.
- *
- * An event handler can set the {@link CExceptionEvent::handled handled}
- * property of the event parameter to be true to indicate no further error
- * handling is needed. Otherwise, the {@link getErrorHandler errorHandler}
- * application component will continue processing the error.
- *
- * @param {Yii.CExceptionEvent} event event parameter
- */
- Yii.CApplication.prototype.onException = function (event) {
- this.raiseEvent('onException',event);
- };
- /**
- * Raised when a JavaScript execution error occurs.
- *
- * An event handler can set the {@link CErrorEvent::handled handled}
- * property of the event parameter to be true to indicate no further error
- * handling is needed. Otherwise, the {@link getErrorHandler errorHandler}
- * application component will continue processing the error.
- *
- * @param {Yii.CErrorEvent} event event parameter
- */
- Yii.CApplication.prototype.onError = function (event) {
- this.raiseEvent('onError',event);
- };
- /**
- * Displays the captured JavaScript error.
- * This method displays the error in HTML when there is
- * no active error handler.
- * @param {Integer} code error code
- * @param {String} message error message
- * @param {String} file error file
- * @param {String} line error line
- */
- Yii.CApplication.prototype.displayError = function (code, message, file, line) {
- var trace, t, i;
- if(YII_DEBUG) {
- document.write("<h1>JavaScript Error [" + code + "]</h1>\n");
- document.write("<p>" + message + "(" + file + ":" + line + ")</p>\n");
- document.write('<table class="yiiLog" width="100%" cellpadding="2" style="border-spacing:1px;font:11px Verdana, Arial, Helvetica, sans-serif;background:#EEEEEE;color:#666666;">');
- document.write('<tr style="background-color:#ccc;">');
- document.write("<th style='width:120px'>Timestamp</th>");
- document.write("<th>Level</th>");
- document.write("<th>Category</th>");
- document.write("<th>Message</th>");
- document.write("</tr>");
- Yii.forEach(Yii._logger.getLogs(), function (i, log) {
- document.write("<tr><td>" + php.date('H:i:s.',log[3]) + php.sprintf('%06d',Number((log[3]-Number(log[3]))*1000000)) + "</td><td>" + log[1] + "</td><td>" + log[2] + "</td><td>" + log[0] + "</td></tr>");
- });
- document.write("</table>");
- document.write("<h2>Stack Trace</h2>");
- document.write('<pre>');
- trace=Yii.CException.prototype.stacktrace();
- // skip the first 3 stacks as they do not tell the error position
- if(php.count(trace)>3) {
- trace=php.array_slice(trace,3);
- }
- for (i in trace) {
- if (trace.hasOwnProperty(i)) {
- document.write(trace[i] + "\n");
- }
- }
- document.write("</pre>");
- }
- else {
- document.write("<h1>JavaScript Error [" + code + "]</h1>\n");
- document.write("<p>" + message + "</p>\n");
- }
- };
- /**
- * Displays the uncaught JavaScript exception.
- * This method displays the exception in HTML when there is
- * no active error handler.
- * @param {Exception} exception the uncaught exception
- */
- Yii.CApplication.prototype.displayException = function (exception) {
- if(YII_DEBUG) {
- document.write('<h1>'+php.get_class(exception)+"</h1>\n");
- document.write('<p>'+exception.getMessage()+'</p>');
- document.write('<pre>'+exception.getTraceAsString()+'</pre>');
- }
- else
- {
- document.write('<h1>'+php.get_class(exception)+"</h1>\n");
- document.write('<p>'+exception.getMessage()+'</p>');
- }
- };
- /**
- * Initializes the class autoloader and error handlers.
- */
- Yii.CApplication.prototype.initSystemHandlers = function () {
- return;
- window.onerror = function (err, loc) {
- Yii.app().displayError("",err);
- return false;
- };
- };
- /**
- * Registers the core application components.
- * @see setComponents
- */
- Yii.CApplication.prototype.registerCoreComponents = function () {
- var components;
- components={
- 'coreMessages':{
- 'class':'CJavaScriptMessageSource',
- 'language':'en_us',
- 'basePath':YII_PATH + '/messages'
- },
- 'db':{
- 'class':'CDbConnection'
- },
- 'messages':{
- 'class':'CJavaScriptMessageSource'
- },
- 'errorHandler':{
- 'class':'CErrorHandler'
- },
- 'securityManager':{
- 'class':'CSecurityManager'
- },
- 'statePersister':{
- 'class':'CStatePersister'
- },
- 'urlManager':{
- 'class':'CUrlManager'
- },
- 'request':{
- 'class':'CHttpRequest'
- },
- 'format':{
- 'class':'CFormatter'
- }
- };
- this.setComponents(components);
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CBehavior is a convenient base class for behavior classes.
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CBehavior.php 3001 2011-02-24 16:42:44Z alexander.makarow $
- * @package system.base
- * @since 1.0.2
- * @author Charles Pick
- * @class
- * @extends Yii.CComponent
- */
- Yii.CBehavior = function CBehavior() {
- };
- Yii.CBehavior.prototype = new Yii.CComponent();
- Yii.CBehavior.prototype.constructor = Yii.CBehavior;
- Yii.CBehavior.prototype._enabled = null;
- Yii.CBehavior.prototype._owner = null;
- /**
- * Declares events and the corresponding event handler methods.
- * The events are defined by the {@link owner} component, while the handler
- * methods by the behavior class. The handlers will be attached to the corresponding
- * events when the behavior is attached to the {@link owner} component; and they
- * will be detached from the events when the behavior is detached from the component.
- * @returns {Object} events (keys) and the corresponding event handler methods (values).
- */
- Yii.CBehavior.prototype.events = function () {
- return {};
- };
- /**
- * Attaches the behavior object to the component.
- * The default implementation will set the {@link owner} property
- * and attach event handlers as declared in {@link events}.
- * Make sure you call the parent implementation if you override this method.
- * @param {Yii.CComponent} owner the component that this behavior is to be attached to.
- */
- Yii.CBehavior.prototype.attach = function (owner) {
- var eventHandler, event, handler;
- this._owner=owner;
- eventHandler = this.events();
- for (event in eventHandler) {
- if (eventHandler.hasOwnProperty(event)) {
- handler = eventHandler[event];
- owner.attachEventHandler(event,[this,handler]);
- }
- }
- };
- /**
- * Detaches the behavior object from the component.
- * The default implementation will unset the {@link owner} property
- * and detach event handlers declared in {@link events}.
- * Make sure you call the parent implementation if you override this method.
- * @param {Yii.CComponent} owner the component that this behavior is to be detached from.
- */
- Yii.CBehavior.prototype.detach = function (owner) {
- var eventHandler, event, handler;
- eventHandler = this.events();
- for (event in eventHandler) {
- if (eventHandler.hasOwnProperty(event)) {
- handler = eventHandler[event];
- owner.detachEventHandler(event,[this,handler]);
- }
- }
- this._owner=null;
- };
- /**
- * @returns {Yii.CComponent} the owner component that this behavior is attached to.
- */
- Yii.CBehavior.prototype.getOwner = function () {
- return this._owner;
- };
- /**
- * @returns {Boolean} whether this behavior is enabled
- */
- Yii.CBehavior.prototype.getEnabled = function () {
- return this._enabled;
- };
- /**
- * @param {Boolean} value whether this behavior is enabled
- */
- Yii.CBehavior.prototype.setEnabled = function (value) {
- var eventHandler, event, handler, eventHandlerList;
- if(this._enabled!=value && this._owner) {
- if(value) {
- eventHandler = this.events();
- for (event in eventHandler) {
- if (eventHandler.hasOwnProperty(event)) {
- handler = eventHandler[event];
- this._owner.attachEventHandler(event,[this,handler]);
- }
- }
- }
- else {
- eventHandlerList = this.events();
- for (event in eventHandlerList) {
- if (eventHandlerList.hasOwnProperty(event)) {
- handler = eventHandlerList[event];
- this._owner.detachEventHandler(event,[this,handler]);
- }
- }
- }
- }
- this._enabled=value;
- }/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CErrorEvent represents the parameter for the {@link CApplication::onError onError} event.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CErrorEvent.php 2799 2011-01-01 19:31:13Z qiang.xue $
- * @package system.base
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CEvent
- */
- Yii.CErrorEvent = function CErrorEvent () {
- };
- Yii.CErrorEvent.prototype = new Yii.CEvent();
- Yii.CErrorEvent.prototype.constructor = Yii.CErrorEvent;
- /**
- * @var {String} error code
- */
- Yii.CErrorEvent.prototype.code = null;
- /**
- * @var {String} error message
- */
- Yii.CErrorEvent.prototype.message = null;
- /**
- * @var {String} error message
- */
- Yii.CErrorEvent.prototype.file = null;
- /**
- * @var {String} error file
- */
- Yii.CErrorEvent.prototype.line = null;
- /**
- * Constructor.
- * @param {Mixed} sender sender of the event
- * @param {String} code error code
- * @param {String} message error message
- * @param {String} file error file
- * @param {Integer} line error line
- */
- Yii.CErrorEvent.prototype.construct = function (sender, code, message, file, line) {
- this.code=code;
- this.message=message;
- this.file=file;
- this.line=line;
- parent.__construct(sender);
- }/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CExceptionEvent represents the parameter for the {@link CApplication::onException onException} event.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CExceptionEvent.php 2799 2011-01-01 19:31:13Z qiang.xue $
- * @package system.base
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CEvent
- */
- Yii.CExceptionEvent = function CExceptionEvent (sender, exception) {
- this.construct(sender, exception);
- };
- Yii.CExceptionEvent.prototype = new Yii.CEvent();
- Yii.CExceptionEvent.prototype.constructor = Yii.CExceptionEvent;
- /**
- * @var {Yii.CException} the exception that this event is about.
- */
- Yii.CExceptionEvent.prototype.exception = null;
- /**
- * Constructor.
- * @param {Mixed} sender sender of the event
- * @param {Yii.CException} exception the exception
- */
- Yii.CExceptionEvent.prototype.construct = function (sender, exception) {
- this.exception=exception;
- Yii.CEvent.prototype.construct.call(this, sender);
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CHttpException represents an exception caused by invalid operations of end-users.
- *
- * The HTTP error code can be obtained via {@link statusCode}.
- * Error handlers may use this status code to decide how to format the error page.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CHttpException.php 2799 2011-01-01 19:31:13Z qiang.xue $
- * @package system.base
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CException
- */
- Yii.CHttpException = function CHttpException (status, message, code) {
-
- this.construct(status, message, code);
- };
- Yii.CHttpException.prototype = new Yii.CException(false);
- Yii.CHttpException.prototype.constructor = Yii.CHttpException;
- /**
- * @var {Integer} HTTP status code, such as 403, 404, 500, etc.
- */
- Yii.CHttpException.prototype.statusCode = null;
- /**
- * Constructor.
- * @param {Integer} status HTTP status code, such as 404, 500, etc.
- * @param {String} message error message
- * @param {Integer} code error code
- */
- Yii.CHttpException.prototype.construct = function (status, message, code) {
- if (message === undefined) {
- message = null;
- }
- if (code === undefined) {
- code = 0;
- }
- this.statusCode=status;
-
- Yii.CException.call(this, message, code);
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CModel is the base class providing the common features needed by data model objects.
- *
- * CModel defines the basic framework for data models that need to be validated.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CModel.php 3087 2011-03-15 02:08:53Z qiang.xue $
- * @package system.base
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CComponent
- */
- Yii.CModel = function CModel () {
- };
- Yii.CModel.prototype = new Yii.CComponent();
- Yii.CModel.prototype.constructor = Yii.CModel;
- Yii.CModel.prototype._errors = {};
- Yii.CModel.prototype._validators = null;
- Yii.CModel.prototype._scenario = '';
- /**
- * Returns the list of attribute names of the model.
- * @returns {Array} list of attribute names.
- * @since 1.0.1
- */
- Yii.CModel.prototype.attributeNames = function () {
-
- };
- /**
- * Returns the validation rules for attributes.
- *
- * This method should be overridden to declare validation rules.
- * Each rule is an object with the following structure:
- * <pre>
- * {
- * attributes: 'attribute list',
- * validator: 'validator name',
- * on: 'scenario name', ...validation parameters...
- * }
- * </pre>
- * where
- * <ul>
- * <li>attributes: specifies the attributes (separated by commas) to be validated;</li>
- * <li>validator: specifies the validator to be used. It can be the name of a model class
- * method, the name of a built-in validator, or a validator class.
- * A validation method must have the following signature:
- * <pre>
- * // params refers to validation parameters given in the rule
- * function validatorName(attribute, params)
- * </pre>
- * A built-in validator refers to one of the validators declared in {@link Yii.CValidator.builtInValidators}.
- * And a validator class is a class extending {@link Yii.CValidator}.</li>
- * <li>on: this specifies the scenarios when the validation rule should be performed.
- * Separate different scenarios with commas. If this option is not set, the rule
- * will be applied in any scenario. Please see {@link Yii.CModel.scenario} for more details about this option.</li>
- * <li>additional parameters are used to initialize the corresponding validator properties.
- * Please refer to individal validator class API for possible properties.</li>
- * </ul>
- *
- * The following are some examples:
- * <pre>
- * [
- * {
- * attributes: 'username',
- * validator: 'required'
- * },
- * {
- * attributes: 'username',
- * validator: 'length',
- * min: 3,
- * max: 12
- * },
- * {
- * attributes: 'password',
- * validator: 'compare',
- * compareAttribute: 'password2',
- * on: 'register'
- * },
- * {
- * attributes: 'password',
- * validator: 'authenticate',
- * on: 'login'
- * }
- * ];
- * </pre>
- *
- * @returns {Array} validation rules to be applied when {@link validate()} is called.
- * @see scenario
- */
- Yii.CModel.prototype.rules = function () {
- return [];
- };
- /**
- * Returns a list of behaviors that this model should behave as.
- * The return value should be an array of behavior configurations indexed by
- * behavior names. Each behavior configuration can be either a string specifying
- * the behavior class or an array of the following structure:
- * <pre>
- * 'behaviorName':{
- * 'class':'path.to.BehaviorClass',
- * 'property1':'value1',
- * 'property2':'value2',
- * }
- * </pre>
- *
- * Note, the behavior classes must implement {@link IBehavior} or extend from
- * {@link CBehavior}. Behaviors declared in this method will be attached
- * to the model when it is instantiated.
- *
- * For more details about behaviors, see {@link CComponent}.
- * @returns {Object} the behavior configurations (behavior name=>behavior configuration)
- * @since 1.0.2
- */
- Yii.CModel.prototype.behaviors = function () {
- return {};
- };
- /**
- * Returns the attribute labels.
- * Attribute labels are mainly used in error messages of validation.
- * By default an attribute label is generated using {@link generateAttributeLabel}.
- * This method allows you to explicitly specify attribute labels.
- *
- * Note, in order to inherit labels defined in the parent class, a child class needs to
- * merge the parent labels with child labels using functions like array_merge().
- *
- * @returns {Object} attribute labels (name=>label)
- * @see generateAttributeLabel
- */
- Yii.CModel.prototype.attributeLabels = function () {
- return {};
- };
- /**
- * Performs the validation.
- *
- * This method executes the validation rules as declared in {@link rules}.
- * Only the rules applicable to the current {@link scenario} will be executed.
- * A rule is considered applicable to a scenario if its 'on' option is not set
- * or contains the scenario.
- *
- * Errors found during the validation can be retrieved via {@link getErrors}.
- *
- * @param {Array} attributes list of attributes that should be validated. Defaults to null,
- * meaning any attribute listed in the applicable validation rules should be
- * validated. If this parameter is given as a list of attributes, only
- * the listed attributes will be validated.
- * @param {Boolean} clearErrors whether to call {@link clearErrors} before performing validation
- * @returns {Boolean} whether the validation is successful without any error.
- * @see beforeValidate
- * @see afterValidate
- */
- Yii.CModel.prototype.validate = function (attributes, clearErrors) {
- var i, limit, validatorList, validator;
- if (attributes === undefined) {
- attributes = null;
- }
- if (clearErrors === undefined) {
- clearErrors = true;
- }
- if (clearErrors) {
- this.clearErrors();
- }
- if(this.beforeValidate()) {
- validatorList = this.getValidators();
-
- limit = validatorList.length;
- for (i = 0; i < limit; i++) {
- validator = validatorList[i];
- validator.validate(this,attributes);
- }
-
- this.afterValidate();
- return !this.hasErrors();
- }
- else {
- return false;
- }
- };
- /**
- * This method is invoked after a model instance is created by new operator.
- * The default implementation raises the {@link onAfterConstruct} event.
- * You may override this method to do postprocessing after model creation.
- * Make sure you call the parent implementation so that the event is raised properly.
- */
- Yii.CModel.prototype.afterConstruct = function () {
- if(this.hasEventHandler('onAfterConstruct')) {
- this.onAfterConstruct(new Yii.CEvent(this));
- }
- };
- /**
- * This method is invoked before validation starts.
- * The default implementation calls {@link onBeforeValidate} to raise an event.
- * You may override this method to do preliminary checks before validation.
- * Make sure the parent implementation is invoked so that the event can be raised.
- * @returns {Boolean} whether validation should be executed. Defaults to true.
- * If false is returned, the validation will stop and the model is considered invalid.
- */
- Yii.CModel.prototype.beforeValidate = function () {
- var event;
-
- event=new Yii.CModelEvent(this);
-
- this.onBeforeValidate(event);
- return event.isValid;
- };
- /**
- * This method is invoked after validation ends.
- * The default implementation calls {@link onAfterValidate} to raise an event.
- * You may override this method to do postprocessing after validation.
- * Make sure the parent implementation is invoked so that the event can be raised.
- */
- Yii.CModel.prototype.afterValidate = function () {
- this.onAfterValidate(new Yii.CEvent(this));
- };
- /**
- * This event is raised after the model instance is created by new operator.
- * @param {Yii.CEvent} event the event parameter
- * @since 1.0.2
- */
- Yii.CModel.prototype.onAfterConstruct = function (event) {
- this.raiseEvent('onAfterConstruct',event);
- };
- /**
- * This event is raised before the validation is performed.
- * @param {Yii.CModelEvent} event the event parameter
- * @since 1.0.2
- */
- Yii.CModel.prototype.onBeforeValidate = function (event) {
- this.raiseEvent('onBeforeValidate',event);
- };
- /**
- * This event is raised after the validation is performed.
- * @param {Yii.CEvent} event the event parameter
- * @since 1.0.2
- */
- Yii.CModel.prototype.onAfterValidate = function (event) {
- this.raiseEvent('onAfterValidate',event);
- };
- /**
- * Returns all the validators declared in the model.
- * This method differs from {@link getValidators} in that the latter
- * would only return the validators applicable to the current {@link scenario}.
- * Also, since this method return a {@link CList} object, you may
- * manipulate it by inserting or removing validators (useful in behaviors).
- * For example, <code>$model->validatorList->add($newValidator)</code>.
- * The change made to the {@link CList} object will persist and reflect
- * in the result of the next call of {@link getValidators}.
- * @returns {Yii.CList} all the validators declared in the model.
- * @since 1.1.2
- */
- Yii.CModel.prototype.getValidatorList = function () {
- if(this._validators===null) {
- this._validators=this.createValidators();
- }
- return this._validators;
- };
- /**
- * Returns the validators applicable to the current {@link scenario}.
- * @param {String} attribute the name of the attribute whose validators should be returned.
- * If this is null, the validators for ALL attributes in the model will be returned.
- * @returns {Array} the validators applicable to the current {@link scenario}.
- * @since 1.0.1
- */
- Yii.CModel.prototype.getValidators = function (attribute) {
- var validators, scenario, i, limit, validator;
- if (attribute === undefined) {
- attribute = null;
- }
- if(this._validators===null) {
- this._validators=this.createValidators();
- }
- validators=[];
- scenario=this.getScenario();
- limit = this._validators.length;
- for (i = 0; i < limit; i++) {
- validator = this._validators[i];
- if(validator.applyTo(scenario)) {
- if(attribute===null || php.in_array(attribute,validator.attributes,true)) {
- validators.push(validator);
- }
- }
- }
-
- return validators;
- };
- /**
- * Creates validator objects based on the specification in {@link rules}.
- * This method is mainly used internally.
- * @returns {Yii.CList} validators built based on {@link rules()}.
- */
- Yii.CModel.prototype.createValidators = function () {
- var validators, i, ruleList, rule, validator, validatorName = null, attributes = null;
- validators=[];
- ruleList = this.rules();
- for (i in ruleList) {
- if (ruleList.hasOwnProperty(i)) {
- rule = ruleList[i];
- attributes = rule.attributes;
- delete rule.attributes;
- validatorName = rule.validator;
- delete rule.validator;
-
- if(attributes !== undefined && validatorName !== undefined) { // attributes, validator name
-
- validator = new Yii.CValidator();
- validators.push(validator.createValidator(validatorName,this,attributes,rule));
- }
- else {
- throw new Yii.CException(Yii.t('yii','{class} has an invalid validation rule. The rule must specify attributes to be validated and the validator name.',
- {'{class}':php.get_class(this)}));
- }
- }
- }
- return validators;
- };
- /**
- * Returns a value indicating whether the attribute is required.
- * This is determined by checking if the attribute is associated with a
- * {@link CRequiredValidator} validation rule in the current {@link scenario}.
- * @param {String} attribute attribute name
- * @returns {Boolean} whether the attribute is required
- * @since 1.0.2
- */
- Yii.CModel.prototype.isAttributeRequired = function (attribute) {
- var i, validatorList, validator;
- validatorList = this.getValidators(attribute);
- for (i in validatorList) {
- if (validatorList.hasOwnProperty(i)) {
- validator = validatorList[i];
- if(validator instanceof Yii.CRequiredValidator) {
- return true;
- }
- }
- }
- return false;
- };
- /**
- * Returns a value indicating whether the attribute is safe for massive assignments.
- * @param {String} attribute attribute name
- * @returns {Boolean} whether the attribute is safe for massive assignments
- * @since 1.1
- */
- Yii.CModel.prototype.isAttributeSafe = function (attribute) {
- var attributes;
- attributes=this.getSafeAttributeNames();
-
- return php.in_array(attribute,attributes);
- };
- /**
- * Returns the text label for the specified attribute.
- * @param {String} attribute the attribute name
- * @returns {String} the attribute label
- * @see generateAttributeLabel
- * @see attributeLabels
- */
- Yii.CModel.prototype.getAttributeLabel = function (attribute) {
- var labels;
- labels=this.attributeLabels();
- if(labels[attribute] !== undefined) {
- return labels[attribute];
- }
- else {
- return this.generateAttributeLabel(attribute);
- }
- };
- /**
- * Returns a value indicating whether there is any validation error.
- * @param {String} attribute attribute name. Use null to check all attributes.
- * @returns {Boolean} whether there is any error.
- */
- Yii.CModel.prototype.hasErrors = function (attribute) {
- var i;
- if (attribute === undefined) {
- attribute = null;
- }
- if(attribute===null) {
- for (i in this._errors) {
- if (this._errors.hasOwnProperty(i)) {
- return true;
- }
- }
- return false;
- }
- else {
- return this._errors[attribute] !== undefined;
- }
- };
- /**
- * Returns the errors for all attribute or a single attribute.
- * @param {String} attribute attribute name. Use null to retrieve errors for all attributes.
- * @returns {Array} errors for all attributes or the specified attribute. Empty array is returned if no error.
- */
- Yii.CModel.prototype.getErrors = function (attribute) {
- if (attribute === undefined) {
- attribute = null;
- }
- if(attribute===null) {
- return this._errors;
- }
- else {
- return this._errors[attribute] !== undefined ? this._errors[attribute] : [];
- }
- };
- /**
- * Returns the first error of the specified attribute.
- * @param {String} attribute attribute name.
- * @returns {String} the error message. Null is returned if no error.
- * @since 1.0.2
- */
- Yii.CModel.prototype.getError = function (attribute) {
- return this._errors[attribute] !== undefined ? php.reset(this._errors[attribute]) : null;
- };
- /**
- * Adds a new error to the specified attribute.
- * @param {String} attribute attribute name
- * @param {String} error new error message
- */
- Yii.CModel.prototype.addError = function (attribute, error) {
- if (this._errors[attribute] === undefined) {
- this._errors[attribute] = [];
- }
- this._errors[attribute].push(error);
- };
- /**
- * Adds a list of errors.
- * @param {Array} errors a list of errors. The array keys must be attribute names.
- * The array values should be error messages. If an attribute has multiple errors,
- * these errors must be given in terms of an array.
- * You may use the result of {@link getErrors} as the value for this parameter.
- * @since 1.0.5
- */
- Yii.CModel.prototype.addErrors = function (errors) {
- var error, i, attribute, e;
- for (attribute in errors) {
- if (errors.hasOwnProperty(attribute)) {
- error = errors[attribute];
- if(Object.prototype.toString.call(error) === '[object Array]') {
- for (i in error) {
- if (error.hasOwnProperty(i)) {
- e = error[i];
- if (this._errors[attribute] === undefined) {
- this._errors[attribute] = [];
- }
- this._errors[attribute].push(e);
- }
- }
- }
- else {
- if (this._errors[attribute] === undefined) {
- this._errors[attribute] = [];
- }
- this._errors[attribute].push(error);
- }
- }
- }
- };
- /**
- * Removes errors for all attributes or a single attribute.
- * @param {String} attribute attribute name. Use null to remove errors for all attribute.
- */
- Yii.CModel.prototype.clearErrors = function (attribute) {
- if (attribute === undefined) {
- attribute = null;
- }
- if(attribute===null) {
- this._errors={};
- }
- else {
- delete this._errors[attribute];
- }
- };
- /**
- * Generates a user friendly attribute label.
- * This is done by replacing underscores or dashes with blanks and
- * changing the first letter of each word to upper case.
- * For example, 'department_name' or 'DepartmentName' becomes 'Department Name'.
- * @param {String} name the column name
- * @returns {String} the attribute label
- */
- Yii.CModel.prototype.generateAttributeLabel = function (name) {
- return php.trim(name.replace(/([A-Z])/g, ' $1').replace(/_|-|\./g, ' ')).replace(/^./, function (str) {
- return str.toUpperCase();
- }
- );
- };
- /**
- * Returns all attribute values.
- * @param {Array} names list of attributes whose value needs to be returned.
- * Defaults to null, meaning all attributes as listed in {@link attributeNames} will be returned.
- * If it is an array, only the attributes in the array will be returned.
- * @returns {Array} attribute values (name=>value).
- */
- Yii.CModel.prototype.getAttributes = function (names) {
- var values, i, nameList, name, values2, n;
- if (names === undefined) {
- names = null;
- }
- values={};
- nameList = this.attributeNames();
- for (i in nameList) {
- if (nameList.hasOwnProperty(i)) {
- name = nameList[i];
- values[name]=this.name;
- }
- }
- if(Object.prototype.toString.call(names) === '[object Array]') {
- values2=[];
- for (n in names) {
- if (names.hasOwnProperty(n)) {
- name = names[n];
- values2[name] = (values[name] !== undefined ? values[name] : null);
- }
- }
- return values2;
- }
- else {
- return values;
- }
- };
- /**
- * Sets the attribute values in a massive way.
- * @param {Array} values attribute values (name=>value) to be set.
- * @param {Boolean} safeOnly whether the assignments should only be done to the safe attributes.
- * A safe attribute is one that is associated with a validation rule in the current {@link scenario}.
- * @see getSafeAttributeNames
- * @see attributeNames
- */
- Yii.CModel.prototype.setAttributes = function (values, safeOnly) {
- var attributes, name, value;
- if (safeOnly === undefined) {
- safeOnly = true;
- }
- if(!values instanceof Object) {
- return;
- }
- attributes=php.array_flip(safeOnly ? this.getSafeAttributeNames() : this.attributeNames());
- for (name in values) {
- if (values.hasOwnProperty(name)) {
- value = values[name];
- if(attributes[name] !== undefined) {
- this.name=value;
- }
- else if(safeOnly) {
- this.onUnsafeAttribute(name,value);
- }
- }
- }
- };
- /**
- * Unsets the attributes.
- * @param {Array} names list of attributes to be set null. If this parameter is not given,
- * all attributes as specified by {@link attributeNames} will have their values unset.
- * @since 1.1.3
- */
- Yii.CModel.prototype.unsetAttributes = function (names) {
- var i, name;
- if (names === undefined) {
- names = null;
- }
- if(names===null) {
- names=this.attributeNames();
- }
- for (i in names) {
- if (names.hasOwnProperty(i)) {
- name = names[i];
- this.name=null;
- }
- }
- };
- /**
- * This method is invoked when an unsafe attribute is being massively assigned.
- * The default implementation will log a warning message if YII_DEBUG is on.
- * It does nothing otherwise.
- * @param {String} name the unsafe attribute name
- * @param {Mixed} value the attribute value
- * @since 1.1.1
- */
- Yii.CModel.prototype.onUnsafeAttribute = function (name, value) {
- if(YII_DEBUG) {
- Yii.log(Yii.t('yii','Failed to set unsafe attribute "{attribute}".',{'{attribute}':name}),Yii.CLogger.LEVEL_WARNING);
- }
- };
- /**
- * Returns the scenario that this model is used in.
- *
- * Scenario affects how validation is performed and which attributes can
- * be massively assigned.
- *
- * A validation rule will be performed when calling {@link validate()}
- * if its 'on' option is not set or contains the current scenario value.
- *
- * And an attribute can be massively assigned if it is associated with
- * a validation rule for the current scenario. Note that an exception is
- * the {@link CUnsafeValidator unsafe} validator which marks the associated
- * attributes as unsafe and not allowed to be massively assigned.
- *
- * @returns {String} the scenario that this model is in.
- * @since 1.0.4
- */
- Yii.CModel.prototype.getScenario = function () {
- return this._scenario;
- };
- /**
- * Sets the scenario for the model.
- * @param {String} value the scenario that this model is in.
- * @see getScenario
- * @since 1.0.4
- */
- Yii.CModel.prototype.setScenario = function (value) {
- this._scenario=value;
- };
- /**
- * Returns the attribute names that are safe to be massively assigned.
- * A safe attribute is one that is associated with a validation rule in the current {@link scenario}.
- * @returns {Array} safe attribute names
- * @since 1.0.2
- */
- Yii.CModel.prototype.getSafeAttributeNames = function () {
- var attributes, unsafe, i, validatorList, validator, n, name, j, k;
- attributes=[];
- unsafe=[];
- validatorList = this.getValidators();
- for (i in validatorList) {
- if (validatorList.hasOwnProperty(i)) {
- validator = validatorList[i];
- if(!validator.safe) {
- for (n in validator.attributes) {
- if (validator.attributes.hasOwnProperty(n)) {
- name = validator.attributes[n];
- unsafe.push(name);
- }
- }
- }
- else
- {
- for (j in validator.attributes) {
- if (validator.attributes.hasOwnProperty(j)) {
- name = validator.attributes[j];
- attributes[name]=true;
- }
- }
- }
- }
- }
- for (k in unsafe) {
- if (unsafe.hasOwnProperty(k)) {
- name = unsafe[k];
- delete attributes[name];
- }
- }
- return php.array_keys(attributes);
- };
- /*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CModelBehavior is a base class for behaviors that are attached to a model component.
- * The model should extend from {@link CModel} or its child classes.
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CModelBehavior.php 2799 2011-01-01 19:31:13Z qiang.xue $
- * @package system.base
- * @since 1.0.2
- * @author Charles Pick
- * @class
- * @extends Yii.CBehavior
- */
- Yii.CModelBehavior = function CModelBehavior() {
- };
- Yii.CModelBehavior.prototype = new Yii.CBehavior();
- Yii.CModelBehavior.prototype.constructor = Yii.CModelBehavior;
- /**
- * Declares events and the corresponding event handler methods.
- * The default implementation returns 'onBeforeValidate' and 'onAfterValidate' events and handlers.
- * If you override this method, make sure you merge the parent result to the return value.
- * @returns {Object} events (keys) and the corresponding event handler methods (values).
- * @see CBehavior::events
- */
- Yii.CModelBehavior.prototype.events = function () {
- return {
- 'onAfterConstruct':'afterConstruct',
- 'onBeforeValidate':'beforeValidate',
- 'onAfterValidate':'afterValidate'
- };
- };
- /**
- * Responds to {@link CModel::onAfterConstruct} event.
- * Overrides this method if you want to handle the corresponding event of the {@link CBehavior::owner owner}.
- * @param {Yii.CEvent} event event parameter
- */
- Yii.CModelBehavior.prototype.afterConstruct = function (event) {
- };
- /**
- * Responds to {@link CModel::onBeforeValidate} event.
- * Overrides this method if you want to handle the corresponding event of the {@link owner}.
- * You may set {@link CModelEvent::isValid} to be false to quit the validation process.
- * @param {Yii.CModelEvent} event event parameter
- */
- Yii.CModelBehavior.prototype.beforeValidate = function (event) {
- };
- /**
- * Responds to {@link CModel::onAfterValidate} event.
- * Overrides this method if you want to handle the corresponding event of the {@link owner}.
- * @param {Yii.CEvent} event event parameter
- */
- Yii.CModelBehavior.prototype.afterValidate = function (event) {
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CModelEvent class.
- *
- * CModelEvent represents the event parameters needed by events raised by a model.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CModelEvent.php 2799 2011-01-01 19:31:13Z qiang.xue $
- * @package system.base
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CEvent
- */
- Yii.CModelEvent = function CModelEvent () {
- };
- Yii.CModelEvent.prototype = new Yii.CEvent();
- Yii.CModelEvent.prototype.constructor = Yii.CModelEvent;
- /**
- * @var {Boolean} whether the model is in valid status and should continue its normal method execution cycles. Defaults to true.
- * For example, when this event is raised in a {@link CFormModel} object that is executing {@link CModel::beforeValidate},
- * if this property is set false by the event handler, the {@link CModel::validate} method will quit after handling this event.
- * If true, the normal execution cycles will continue, including performing the real validations and calling
- * {@link CModel::afterValidate}.
- */
- Yii.CModelEvent.prototype.isValid = true;
- /**
- * @var {Yii.CDbCrireria} the query criteria that is passed as a parameter to a find method of {@link CActiveRecord}.
- * Note that this property is only used by {@link CActiveRecord::onBeforeFind} event.
- * This property could be null.
- * @since 1.1.5
- */
- Yii.CModelEvent.prototype.criteria = null;/*global Yii, php, sjcl, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CSecurityManager provides private keys, hashing and encryption functions.
- *
- * CSecurityManager is used by Yii components and applications for security-related purpose.
- * For example, it is used in cookie validation feature to prevent cookie data
- * from being tampered.
- *
- * CSecurityManager is mainly used to protect data from being tampered and viewed.
- * It can generate HMAC and encrypt the data. The private key used to generate HMAC
- * is set by {@link setValidationKey ValidationKey}. The key used to encrypt data is
- * specified by {@link setEncryptionKey EncryptionKey}. If the above keys are not
- * explicitly set, random keys will be generated and used.
- *
- * To protected data with HMAC, call {@link hashData()}; and to check if the data
- * is tampered, call {@link validateData()}, which will return the real data if
- * it is not tampered. The algorithm used to generated HMAC is specified by
- * {@link validation}.
- *
- * To encrypt and decrypt data, call {@link encrypt()} and {@link decrypt()}
- * respectively, which uses 3DES encryption algorithm. Note, the PHP Mcrypt
- * extension must be installed and loaded.
- *
- * CSecurityManager is a core application component that can be accessed via
- * {@link CApplication::getSecurityManager()}.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CSecurityManager.php 3001 2011-02-24 16:42:44Z alexander.makarow $
- * @package system.base
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CApplicationComponent
- */
- Yii.CSecurityManager = function CSecurityManager() {
- };
- Yii.CSecurityManager.prototype = new Yii.CApplicationComponent();
- Yii.CSecurityManager.prototype.constructor = Yii.CSecurityManager;
- /**
- * @const
- */
- Yii.CSecurityManager.STATE_VALIDATION_KEY = 'Yii.CSecurityManager.validationkey';
- /**
- * @const
- */
- Yii.CSecurityManager.STATE_ENCRYPTION_KEY = 'Yii.CSecurityManager.encryptionkey';
- /**
- * @var {String} the name of the hashing algorithm to be used by {@link computeHMAC}.
- *
- * Defaults to 'sha1', meaning using SHA1 hash algorithm.
- * @since 1.1.3
- */
- Yii.CSecurityManager.prototype.hashAlgorithm = 'sha1';
-
- Yii.CSecurityManager.prototype._validationKey = null;
- Yii.CSecurityManager.prototype._encryptionKey = null;
- /**
- * @returns {String} a randomly generated private key
- */
- Yii.CSecurityManager.prototype.generateRandomKey = function () {
- return php.sprintf('%08x%08x%08x%08x',php.mt_rand(),php.mt_rand(),php.mt_rand(),php.mt_rand());
- };
- /**
- * @returns {String} the private key used to generate HMAC.
- * If the key is not explicitly set, a random one is generated and returned.
- */
- Yii.CSecurityManager.prototype.getValidationKey = function () {
- var key;
- if(this._validationKey!==null) {
- return this._validationKey;
- }
- else {
- if((key=Yii.app().getGlobalState(this.STATE_VALIDATION_KEY))!==null) {
- this.setValidationKey(key);
- }
- else {
- key=this.generateRandomKey();
- this.setValidationKey(key);
- Yii.app().setGlobalState(this.STATE_VALIDATION_KEY,key);
- }
- return this._validationKey;
- }
- };
- /**
- * @param {String} value the key used to generate HMAC
- * @throws {Yii.CException} if the key is empty
- */
- Yii.CSecurityManager.prototype.setValidationKey = function (value) {
- if(!php.empty(value)) {
- this._validationKey=value;
- }
- else {
- throw new Yii.CException(Yii.t('yii','CSecurityManager.validationKey cannot be empty.'));
- }
- };
- /**
- * @returns {String} the private key used to encrypt/decrypt data.
- * If the key is not explicitly set, a random one is generated and returned.
- */
- Yii.CSecurityManager.prototype.getEncryptionKey = function () {
- var key;
- if(this._encryptionKey!==null) {
- return this._encryptionKey;
- }
- else {
- if((key=Yii.app().getGlobalState(this.STATE_ENCRYPTION_KEY))!==null) {
- this.setEncryptionKey(key);
- }
- else {
- key=this.generateRandomKey();
- this.setEncryptionKey(key);
- Yii.app().setGlobalState(this.STATE_ENCRYPTION_KEY,key);
- }
- return this._encryptionKey;
- }
- };
- /**
- * @param {String} value the key used to encrypt/decrypt data.
- * @throws {Yii.CException} if the key is empty
- */
- Yii.CSecurityManager.prototype.setEncryptionKey = function (value) {
- if(!php.empty(value)) {
- this._encryptionKey=value;
- }
- else {
- throw new Yii.CException(Yii.t('yii','CSecurityManager.encryptionKey cannot be empty.'));
- }
- };
- /**
- * This method has been deprecated since version 1.1.3.
- * Please use {@link hashAlgorithm} instead.
- */
- Yii.CSecurityManager.prototype.getValidation = function () {
- return this.hashAlgorithm;
- };
- /**
- * This method has been deprecated since version 1.1.3.
- * Please use {@link hashAlgorithm} instead.
- * @param {String} value -
- */
- Yii.CSecurityManager.prototype.setValidation = function (value) {
- this.hashAlgorithm=value;
- };
- /**
- * Encrypts data.
- * @param {String} data data to be encrypted.
- * @param {String} key the decryption key. This defaults to null, meaning using {@link getEncryptionKey EncryptionKey}.
- * @returns {String} the encrypted data
- * @throws {Yii.CException} if PHP Mcrypt extension is not loaded
- */
- Yii.CSecurityManager.prototype.encrypt = function (data, key) {
- var module, iv, encrypted;
- if (key === undefined) {
- key = null;
- }
- module=this.openCryptModule();
- key=key===null ? php.md5(this.getEncryptionKey()) : key;
- encrypted = module.encrypt(key, data);
- return encrypted;
- };
- /**
- * Decrypts data
- * @param {String} data data to be decrypted.
- * @param {String} key the decryption key. This defaults to null, meaning using {@link getEncryptionKey EncryptionKey}.
- * @returns {String} the decrypted data
- * @throws {Yii.CException} if PHP Mcrypt extension is not loaded
- */
- Yii.CSecurityManager.prototype.decrypt = function (data, key) {
- var module, ivSize, iv, decrypted;
- if (key === undefined) {
- key = null;
- }
- module=this.openCryptModule();
- key=key===null ? php.md5(this.getEncryptionKey()) : key;
- decrypted = module.decrypt(key, data);
- return decrypted;
- };
- /**
- * Opens the mcrypt module with the configuration specified in {@link cryptAlgorithm}.
- * @returns {Resource} the mycrypt module handle.
- * @since 1.1.3
- */
- Yii.CSecurityManager.prototype.openCryptModule = function () {
- var module;
- if(sjcl !== undefined) {
- return sjcl;
- }
- else {
- throw new Yii.CException(Yii.t('yii','CSecurityManager requires the Stanford Javascript Crypto Library to be loaded in order to use data encryption feature.'));
- }
- };
- /**
- * Prefixes data with an HMAC.
- * @param {String} data data to be hashed.
- * @param {String} key the private key to be used for generating HMAC. Defaults to null, meaning using {@link validationKey}.
- * @returns {String} data prefixed with HMAC
- */
- Yii.CSecurityManager.prototype.hashData = function (data, key) {
- if (key === undefined) {
- key = null;
- }
- return this.computeHMAC(data,key)+data;
- };
- /**
- * Validates if data is tampered.
- * @param {String} data data to be validated. The data must be previously
- * generated using {@link hashData()}.
- * @param {String} key the private key to be used for generating HMAC. Defaults to null, meaning using {@link validationKey}.
- * @returns {String} the real data with HMAC stripped off. False if the data
- * is tampered.
- */
- Yii.CSecurityManager.prototype.validateData = function (data, key) {
- var len, hmac, data2;
- if (key === undefined) {
- key = null;
- }
- len=php.strlen(this.computeHMAC('test'));
-
- if(php.strlen(data)>=len) {
- hmac=data.slice(0, len);
- data2=data.slice(len);
- return hmac===this.computeHMAC(data2,key)?data2:false;
- }
- else {
- return false;
- }
- };
- /**
- * Computes the HMAC for the data with {@link getValidationKey ValidationKey}.
- * @param {String} data data to be generated HMAC
- * @param {String} key the private key to be used for generating HMAC. Defaults to null, meaning using {@link validationKey}.
- * @returns {String} the HMAC for the data
- */
- Yii.CSecurityManager.prototype.computeHMAC = function (data, key) {
- var pack, func, hmac;
- if (key === undefined) {
- key = null;
- }
- if(key===null) {
- key=this.getValidationKey();
- }
- hmac = new sjcl.misc.hmac(key);
- return php.md5(hmac.encrypt(data).join(""));
-
- };
-
- /*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CStatePersister implements a file-based persistent data storage.
- *
- * It can be used to keep data available through multiple requests and sessions.
- *
- * By default, CStatePersister stores data in a file named 'state.bin' that is located
- * under the application {@link CApplication::getRuntimePath runtime path}.
- * You may change the location by setting the {@link stateFile} property.
- *
- * To retrieve the data from CStatePersister, call {@link load()}. To save the data,
- * call {@link save()}.
- *
- * Comparison among state persister, session and cache is as follows:
- * <ul>
- * <li>session: data persisting within a single user session.</li>
- * <li>state persister: data persisting through all requests/sessions (e.g. hit counter).</li>
- * <li>cache: volatile and fast storage. It may be used as storage medium for session or state persister.</li>
- * </ul>
- *
- * Since server resource is often limited, be cautious if you plan to use CStatePersister
- * to store large amount of data. You should also consider using database-based persister
- * to improve the throughput.
- *
- * CStatePersister is a core application component used to store global application state.
- * It may be accessed via {@link CApplication::getStatePersister()}.
- * page state persistent method based on cache.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CStatePersister.php 3165 2011-04-06 08:27:40Z mdomba $
- * @package system.base
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CApplicationComponent
- */
- Yii.CStatePersister = function CStatePersister() {
- };
- Yii.CStatePersister.prototype = new Yii.CApplicationComponent();
- Yii.CStatePersister.prototype.constructor = Yii.CStatePersister;
- /**
- * Initializes the component.
- * This method overrides the parent implementation by making sure the
- * browser supports localStorage
- */
- Yii.CStatePersister.prototype.init = function () {
- Yii.CApplicationComponent.prototype.init.call(this);
-
- try {
- return "localStorage" in window && window.localStorage !== null;
- }
- catch (e) {
- throw new Yii.CException(Yii.t('yii','Unable to access local storage, please ensure that you\'re using a modern browser!'));
- }
- };
- /**
- * Loads state data from persistent storage.
- * @returns {Mixed} state data. Null if no state data available.
- */
- Yii.CStatePersister.prototype.load = function () {
- var state = {}, i, value;
- if(window.localStorage.length !== 0) {
-
- for (i in window.localStorage) {
- if (window.localStorage.hasOwnProperty(i)) {
- try {
- state[i] = Yii.CJSON.decode(window.localStorage[i]);
- }
- catch (e) {
- state[i] = window.localStorage[i];
- }
- }
- }
- return state;
- }
- else {
- return null;
- }
- };
- /**
- * Saves application state in persistent storage.
- * @param {Mixed} state state data (must be serializable).
- */
- Yii.CStatePersister.prototype.save = function (state) {
- var i;
- window.localStorage.clear();
- for(i in state) {
- if (state.hasOwnProperty(i)) {
- window.localStorage[i] = Yii.CJSON.encode(state[i]);
- }
- }
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CCache is the base class for cache classes with different cache storage implementation.
- *
- * A data item can be stored in cache by calling {@link set} and be retrieved back
- * later by {@link get}. In both operations, a key identifying the data item is required.
- * An expiration time and/or a dependency can also be specified when calling {@link set}.
- * If the data item expires or the dependency changes, calling {@link get} will not
- * return back the data item.
- *
- * Note, by definition, cache does not ensure the existence of a value
- * even if it does not expire. Cache is not meant to be a persistent storage.
- *
- * CCache implements the interface {@link ICache} with the following methods:
- * <ul>
- * <li>{@link get} : retrieve the value with a key (if any) from cache</li>
- * <li>{@link set} : store the value with a key into cache</li>
- * <li>{@link add} : store the value only if cache does not have this key</li>
- * <li>{@link delete} : delete the value with the specified key from cache</li>
- * <li>{@link flush} : delete all values from cache</li>
- * </ul>
- *
- * Child classes must implement the following methods:
- * <ul>
- * <li>{@link getValue}</li>
- * <li>{@link setValue}</li>
- * <li>{@link addValue}</li>
- * <li>{@link deleteValue}</li>
- * <li>{@link flush} (optional)</li>
- * </ul>
- *
- * CCache also implements ArrayAccess so that it can be used like an array.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CCache.php 3001 2011-02-24 16:42:44Z alexander.makarow $
- * @package system.caching
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CApplicationComponent
- */
- Yii.CCache = function CCache () {
- };
- Yii.CCache.prototype = new Yii.CApplicationComponent();
- Yii.CCache.prototype.constructor = Yii.CCache;
- /**
- * @var {String} a string prefixed to every cache key so that it is unique. Defaults to {@link CApplication::getId() application ID}.
- */
- Yii.CCache.prototype.keyPrefix = null;
- /**
- * Initializes the application component.
- * This method overrides the parent implementation by setting default cache key prefix.
- */
- Yii.CCache.prototype.init = function () {
- Yii.CApplicationComponent.prototype.init.call(this);
- if(this.keyPrefix===null) {
- this.keyPrefix=Yii.app().getId();
- }
- };
- /**
- * @param {String} key a key identifying a value to be cached
- * @returns {Sring} a key generated from the provided key which ensures the uniqueness across applications
- */
- Yii.CCache.prototype.generateUniqueKey = function (key) {
- return php.md5(this.keyPrefix+key);
- };
- /**
- * Retrieves a value from cache with a specified key.
- * @param {String} id a key identifying the cached value
- * @returns {Mixed} the value stored in cache, false if the value is not in the cache, expired or the dependency has changed.
- */
- Yii.CCache.prototype.get = function (id) {
- var value, data;
- if((value=this.getValue(this.generateUniqueKey(id)))!==false) {
- data = value;
-
- if (!data) {
- return false;
- }
- if(Object.prototype.toString.call(data) !== '[object Array]') {
- if (data.length > 0) {
- try {
- data = Yii.CJSON.decode(data);
- }
- catch (e) {
- return false;
- }
- }
- else {
- return false;
- }
- }
- if (false && data[1] !== undefined && data[1] !== {}) {
- data[1] = Yii.createComponent(data[1]);
- }
- if(data[1] === null || !(data[1] instanceof Yii.CCacheDependency) || !data[1].getHasChanged()) {
- Yii.trace('Serving "'+id+'" from cache','system.caching.'+this.getClassName());
- return data[0];
- }
- }
- return false;
- };
- /**
- * Retrieves multiple values from cache with the specified keys.
- * Some caches (such as memcache, apc) allow retrieving multiple cached values at one time,
- * which may improve the performance since it reduces the communication cost.
- * In case a cache doesn't support this feature natively, it will be simulated by this method.
- * @param {Array} ids list of keys identifying the cached values
- * @returns {Array} list of cached values corresponding to the specified keys. The array
- * is returned in terms of (key,value) pairs.
- * If a value is not cached or expired, the corresponding array value will be false.
- * @since 1.0.8
- */
- Yii.CCache.prototype.mget = function (ids) {
- var uniqueIDs, results, i, id, values, uniqueID, data;
- uniqueIDs={};
- results={};
- for (i in ids) {
- if (ids.hasOwnProperty(i)) {
- id = ids[i];
- uniqueIDs[id]=this.generateUniqueKey(id);
- results[id]=false;
- }
- }
- values=this.getValues(uniqueIDs);
- for (id in uniqueIDs) {
- if (uniqueIDs.hasOwnProperty(id)) {
- uniqueID = uniqueIDs[id];
- if(values[uniqueID] === undefined) {
- continue;
- }
- data=Yii.CJSON.decode(values[uniqueID]);
- data = value;
- if(Object.prototype.toString.call(data) !== '[object Array]') {
- if (data.length > 0) {
- try {
- data = Yii.CJSON.decode(data);
- }
- catch (e) {
- return false;
- }
- }
- else {
- return false;
- }
- }
- if (data[1] !== undefined && data[1] !== {}) {
- data[1] = Yii.createComponent(data[1]);
- }
- if(!(data[1] instanceof Yii.CCacheDependency) || !data[1].getHasChanged()) {
- Yii.trace('Serving "'+id+'" from cache','system.caching.'+this.getClassName());
- results[id] = data[0];
- }
- }
- }
- return results;
- };
- /**
- * Stores a value identified by a key into cache.
- * If the cache already contains such a key, the existing value and
- * expiration time will be replaced with the new ones.
- *
- * @param {String} id the key identifying the value to be cached
- * @param {Mixed} value the value to be cached
- * @param {Integer} expire the number of seconds in which the cached value will expire. 0 means never expire.
- * @param {ICacheDependency} dependency dependency of the cached item. If the dependency changes, the item is labeled invalid.
- * @returns {Boolean} true if the value is successfully stored into cache, false otherwise
- */
- Yii.CCache.prototype.set = function (id, value, expire, dependency) {
- var data;
- if (expire === undefined) {
- expire = 0;
- }
- if (dependency === undefined) {
- dependency = null;
- }
- Yii.trace('Saving "'+id+'" to cache','system.caching.'+this.getClassName());
- if(dependency!==null) {
- dependency.evaluateDependency();
- }
- data=[value,dependency];
- return this.setValue(this.generateUniqueKey(id),Yii.CJSON.encode(data),expire);
- };
- /**
- * Stores a value identified by a key into cache if the cache does not contain this key.
- * Nothing will be done if the cache already contains the key.
- * @param {String} id the key identifying the value to be cached
- * @param {Mixed} value the value to be cached
- * @param {Integer} expire the number of seconds in which the cached value will expire. 0 means never expire.
- * @param {ICacheDependency} dependency dependency of the cached item. If the dependency changes, the item is labeled invalid.
- * @returns {Boolean} true if the value is successfully stored into cache, false otherwise
- */
- Yii.CCache.prototype.add = function (id, value, expire, dependency) {
- var data;
- if (expire === undefined) {
- expire = 0;
- }
- if (dependency === undefined) {
- dependency = null;
- }
- Yii.trace('Adding "'+id+'" to cache','system.caching.'+this.getClassName());
- if(dependency!==null) {
- dependency.evaluateDependency();
- }
- data=[value,dependency];
- return this.addValue(this.generateUniqueKey(id),Yii.CJSON.encode(data),expire);
- };
- /**
- * Deletes a value with the specified key from cache
- * @param {String} id the key of the value to be deleted
- * @returns {Boolean} if no error happens during deletion
- */
- Yii.CCache.prototype.remove = function (id) {
- Yii.trace('Deleting "'+id+'" from cache','system.caching.'+this.getClassName());
- return this.deleteValue(this.generateUniqueKey(id));
- };
- /**
- * Deletes all values from cache.
- * Be careful of performing this operation if the cache is shared by multiple applications.
- * @returns {Boolean} whether the flush operation was successful.
- */
- Yii.CCache.prototype.flush = function () {
- Yii.trace('Flushing cache','system.caching.'+this.getClassName());
- return this.flushValues();
- };
- /**
- * Retrieves a value from cache with a specified key.
- * This method should be implemented by child classes to retrieve the data
- * from specific cache storage. The uniqueness and dependency are handled
- * in {@link get()} already. So only the implementation of data retrieval
- * is needed.
- * @param {String} key a unique key identifying the cached value
- * @returns {String} the value stored in cache, false if the value is not in the cache or expired.
- * @throws {Yii.CException} if this method is not overridden by child classes
- */
- Yii.CCache.prototype.getValue = function (key) {
- throw new Yii.CException(Yii.t('yii','{className} does not support get() functionality.',
- {'{className}':this.getClassName()}));
- };
- /**
- * Retrieves multiple values from cache with the specified keys.
- * The default implementation simply calls {@link getValue} multiple
- * times to retrieve the cached values one by one.
- * If the underlying cache storage supports multiget, this method should
- * be overridden to exploit that feature.
- * @param {Array} keys a list of keys identifying the cached values
- * @returns {Object} a list of cached values indexed by the keys
- * @since 1.0.8
- */
- Yii.CCache.prototype.getValues = function (keys) {
- var results, i, key;
- results={};
- for (i in keys) {
- if (keys.hasOwnProperty(i)) {
- key = keys[i];
- results[key]=this.getValue(key);
- }
- }
- return results;
- };
- /**
- * Stores a value identified by a key in cache.
- * This method should be implemented by child classes to store the data
- * in specific cache storage. The uniqueness and dependency are handled
- * in {@link set()} already. So only the implementation of data storage
- * is needed.
- *
- * @param {String} key the key identifying the value to be cached
- * @param {String} value the value to be cached
- * @param {Integer} expire the number of seconds in which the cached value will expire. 0 means never expire.
- * @returns {Boolean} true if the value is successfully stored into cache, false otherwise
- * @throws {Yii.CException} if this method is not overridden by child classes
- */
- Yii.CCache.prototype.setValue = function (key, value, expire) {
- throw new Yii.CException(Yii.t('yii','{className} does not support set() functionality.',
- {'{className}':this.getClassName()}));
- };
- /**
- * Stores a value identified by a key into cache if the cache does not contain this key.
- * This method should be implemented by child classes to store the data
- * in specific cache storage. The uniqueness and dependency are handled
- * in {@link add()} already. So only the implementation of data storage
- * is needed.
- *
- * @param {String} key the key identifying the value to be cached
- * @param {String} value the value to be cached
- * @param {Integer} expire the number of seconds in which the cached value will expire. 0 means never expire.
- * @returns {Boolean} true if the value is successfully stored into cache, false otherwise
- * @throws {Yii.CException} if this method is not overridden by child classes
- */
- Yii.CCache.prototype.addValue = function (key, value, expire) {
- throw new Yii.CException(Yii.t('yii','{className} does not support add() functionality.',
- {'{className}':this.getClassName()}));
- };
- /**
- * Deletes a value with the specified key from cache
- * This method should be implemented by child classes to delete the data from actual cache storage.
- * @param {String} key the key of the value to be deleted
- * @returns {Boolean} if no error happens during deletion
- * @throws {Yii.CException} if this method is not overridden by child classes
- */
- Yii.CCache.prototype.deleteValue = function (key) {
- throw new Yii.CException(Yii.t('yii','{className} does not support delete() functionality.',
- {'{className}':this.getClassName()}));
- };
- /**
- * Deletes all values from cache.
- * Child classes may implement this method to realize the flush operation.
- * @returns {Boolean} whether the flush operation was successful.
- * @throws {Yii.CException} if this method is not overridden by child classes
- * @since 1.1.5
- */
- Yii.CCache.prototype.flushValues = function () {
- throw new Yii.CException(Yii.t('yii','{className} does not support flushValues() functionality.',
- {'{className}':this.getClassName()}));
- };
- /**
- * Returns whether there is a cache entry with a specified key.
- * This method is required by the interface ArrayAccess.
- * @param {String} id a key identifying the cached value
- * @returns {Boolean}
- */
- Yii.CCache.prototype.offsetExists = function (id) {
- return this.get(id)!==false;
- };
- /**
- * Retrieves the value from cache with a specified key.
- * This method is required by the interface ArrayAccess.
- * @param {String} id a key identifying the cached value
- * @returns {Mixed} the value stored in cache, false if the value is not in the cache or expired.
- */
- Yii.CCache.prototype.offsetGet = function (id) {
- return this.get(id);
- };
- /**
- * Stores the value identified by a key into cache.
- * If the cache already contains such a key, the existing value will be
- * replaced with the new ones. To add expiration and dependencies, use the set() method.
- * This method is required by the interface ArrayAccess.
- * @param {String} id the key identifying the value to be cached
- * @param {Mixed} value the value to be cached
- */
- Yii.CCache.prototype.offsetSet = function (id, value) {
- this.set(id, value);
- };
- /**
- * Deletes the value with the specified key from cache
- * This method is required by the interface ArrayAccess.
- * @param {String} id the key of the value to be deleted
- * @returns {Boolean} if no error happens during deletion
- */
- Yii.CCache.prototype.offsetUnset = function (id) {
- this.remove(id);
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CLocalCache implements a cache application component based on localStorage
- * @package system.caching
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CCache
- */
- Yii.CLocalCache = function CLocalCache () {
- };
- Yii.CLocalCache.prototype = new Yii.CCache();
- Yii.CLocalCache.prototype.constructor = Yii.CLocalCache;
- /**
- * Retrieves a value from cache with a specified key.
- * This is the implementation of the method declared in the parent class.
- * @param {String} key a unique key identifying the cached value
- * @returns {String} the value stored in cache, false if the value is not in the cache or expired.
- */
- Yii.CLocalCache.prototype.getValue = function (key) {
- var raw, item, expiry, now;
- raw = localStorage.getItem(key);
- if (raw === null) {
- return false;
- }
- try {
- item = Yii.CJSON.decode(raw);
- now = php.time();
- expiry = item.shift();
- if (expiry !== 0 && expiry < now) {
- localStorage.removeItem(key);
- return false;
- }
- return item.shift();
- }
- catch (e) {
- return raw;
- }
- };
- /**
- * Stores a value identified by a key in cache.
- * This is the implementation of the method declared in the parent class.
- *
- * @param {String} key the key identifying the value to be cached
- * @param {String} value the value to be cached
- * @param {Integer} expire the number of seconds in which the cached value will expire. 0 means never expire.
- * @returns {Boolean} true if the value is successfully stored into cache, false otherwise
- */
- Yii.CLocalCache.prototype.setValue = function (key, value, expire) {
- if(expire>0) {
- expire+=php.time();
- }
- else {
- expire=0;
- }
-
- return localStorage.setItem(key, Yii.CJSON.encode([expire,value]));
-
- };
- /**
- * Stores a value identified by a key into cache if the cache does not contain this key.
- * This is the implementation of the method declared in the parent class.
- *
- * @param {String} key the key identifying the value to be cached
- * @param {String} value the value to be cached
- * @param {Integer} expire the number of seconds in which the cached value will expire. 0 means never expire.
- * @returns {Boolean} true if the value is successfully stored into cache, false otherwise
- */
- Yii.CLocalCache.prototype.addValue = function (key, value, expire) {
- if(expire>0) {
- expire+=php.time();
- }
- else {
- expire=0;
- }
- // TODO: expiry!
- return localStorage.setItem(key, value);
- };
- /**
- * Deletes a value with the specified key from cache
- * This is the implementation of the method declared in the parent class.
- * @param {String} key the key of the value to be deleted
- * @returns {Boolean} if no error happens during deletion
- */
- Yii.CLocalCache.prototype.remove = function (key) {
- return localStorage.removeItem(key);
- };
- /**
- * Deletes all values from cache.
- * This is the implementation of the method declared in the parent class.
- * @returns {Boolean} whether the flush operation was successful.
- * @since 1.1.5
- */
- Yii.CLocalCache.prototype.flushValues = function () {
- return localStorage.clear();
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CSessionCache implements a cache application component based on sessionStorage
- * @package system.caching
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CCache
- */
- Yii.CSessionCache = function CSessionCache () {
- };
- Yii.CSessionCache.prototype = new Yii.CCache();
- Yii.CSessionCache.prototype.constructor = Yii.CSessionCache;
- /**
- * Retrieves a value from cache with a specified key.
- * This is the implementation of the method declared in the parent class.
- * @param {String} key a unique key identifying the cached value
- * @returns {String} the value stored in cache, false if the value is not in the cache or expired.
- */
- Yii.CSessionCache.prototype.getValue = function (key) {
- var raw, item, expiry, now;
- raw = sessionStorage.getItem(key);
- if (raw === null) {
- return false;
- }
- try {
- item = Yii.CJSON.decode(raw);
- now = php.time();
- expiry = item.shift();
- if (expiry !== 0 && expiry < now) {
- sessionStorage.removeItem(key);
- return false;
- }
- return item.shift();
- }
- catch (e) {
- return raw;
- }
- };
- /**
- * Stores a value identified by a key in cache.
- * This is the implementation of the method declared in the parent class.
- *
- * @param {String} key the key identifying the value to be cached
- * @param {String} value the value to be cached
- * @param {Integer} expire the number of seconds in which the cached value will expire. 0 means never expire.
- * @returns {Boolean} true if the value is successfully stored into cache, false otherwise
- */
- Yii.CSessionCache.prototype.setValue = function (key, value, expire) {
- if(expire>0) {
- expire+=php.time();
- }
- else {
- expire=0;
- }
-
- return sessionStorage.setItem(key, Yii.CJSON.encode([expire,value]));
-
- };
- /**
- * Stores a value identified by a key into cache if the cache does not contain this key.
- * This is the implementation of the method declared in the parent class.
- *
- * @param {String} key the key identifying the value to be cached
- * @param {String} value the value to be cached
- * @param {Integer} expire the number of seconds in which the cached value will expire. 0 means never expire.
- * @returns {Boolean} true if the value is successfully stored into cache, false otherwise
- */
- Yii.CSessionCache.prototype.addValue = function (key, value, expire) {
- if(expire>0) {
- expire+=php.time();
- }
- else {
- expire=0;
- }
- // TODO: expiry!
- return sessionStorage.setItem(key, value);
- };
- /**
- * Deletes a value with the specified key from cache
- * This is the implementation of the method declared in the parent class.
- * @param {String} key the key of the value to be deleted
- * @returns {Boolean} if no error happens during deletion
- */
- Yii.CSessionCache.prototype.remove = function (key) {
- return sessionStorage.removeItem(key);
- };
- /**
- * Deletes all values from cache.
- * This is the implementation of the method declared in the parent class.
- * @returns {Boolean} whether the flush operation was successful.
- * @since 1.1.5
- */
- Yii.CSessionCache.prototype.flushValues = function () {
- return sessionStorage.clear();
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CAttributeCollection implements a collection for storing attribute names and values.
- *
- * Besides all functionalities provided by {@link CMap}, CAttributeCollection
- * allows you to get and set attribute values like getting and setting
- * properties. For example, the following usages are all valid for a
- * CAttributeCollection object:
- * <pre>
- * collection.text='text'; // same as: $collection->add('text','text');
- * document.write(collection.text); // same as: echo $collection->itemAt('text');
- * </pre>
- *
- * The case sensitivity of attribute names can be toggled by setting the
- * {@link caseSensitive} property of the collection.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CAttributeCollection.php 3001 2011-02-24 16:42:44Z alexander.makarow $
- * @package system.collections
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CMap
- */
- Yii.CAttributeCollection = function CAttributeCollection(data, readOnly) {
- this.construct(data, readOnly);
-
- };
- Yii.CAttributeCollection.prototype = new Yii.CMap();
- Yii.CAttributeCollection.prototype.constructor = Yii.CAttributeCollection;
- /**
- * @var {Boolean} whether the keys are case-sensitive. Defaults to false.
- */
- Yii.CAttributeCollection.prototype.caseSensitive = false;
- /**
- * Returns a property value or an event handler list by property or event name.
- * This method overrides the parent implementation by returning
- * a key value if the key exists in the collection.
- * @param {String} name the property name or the event name
- * @returns {Mixed} the property value or the event handler list
- * @throws {Yii.CException} if the property/event is not defined.
- */
- Yii.CAttributeCollection.prototype.get = function (name) {
- if(this.contains(name)) {
- return this.itemAt(name);
- }
- else {
- return Yii.CMap.prototype.get.call(this, name);
- }
- };
- /**
- * Sets value of a component property.
- * This method overrides the parent implementation by adding a new key value
- * to the collection.
- * @param {String} name the property name or event name
- * @param {Mixed} value the property value or event handler
- * @throws {Yii.CException} If the property is not defined or read-only.
- */
- Yii.CAttributeCollection.prototype.set = function (name, value) {
- this.add(name,value);
- };
- /**
- * Checks if a property value is null.
- * This method overrides the parent implementation by checking
- * if the key exists in the collection and contains a non-null value.
- * @param {String} name the property name or the event name
- * @returns {Boolean} whether the property value is null
- * @since 1.0.1
- */
- Yii.CAttributeCollection.prototype.isset = function (name) {
- if(this.contains(name)) {
- return this.itemAt(name)!==null;
- }
- else {
- return Yii.CMap.prototype.isset.call(this, name);
- }
- };
- /**
- * Sets a component property to be null.
- * This method overrides the parent implementation by clearing
- * the specified key value.
- * @param {String} name the property name or the event name
- * @since 1.0.1
- */
- Yii.CAttributeCollection.prototype.unset = function (name) {
- this.remove(name);
- };
- /**
- * Returns the item with the specified key.
- * This overrides the parent implementation by converting the key to lower case first if {@link caseSensitive} is false.
- * @param {Mixed} key the key
- * @returns {Mixed} the element at the offset, null if no element is found at the offset
- */
- Yii.CAttributeCollection.prototype.itemAt = function (key) {
- if(this.caseSensitive) {
- return Yii.CMap.prototype.itemAt.call(this,key);
- }
- else {
- return Yii.CMap.prototype.itemAt.call(this,key.toLowerCase());
- }
- };
- /**
- * Adds an item into the map.
- * This overrides the parent implementation by converting the key to lower case first if {@link caseSensitive} is false.
- * @param {Mixed} key key
- * @param {Mixed} value value
- */
- Yii.CAttributeCollection.prototype.add = function (key, value) {
- if(this.caseSensitive) {
- Yii.CMap.prototype.add.call(this, key,value);
- }
- else {
- Yii.CMap.prototype.add.call(this, key.toLowerCase(),value);
- }
- };
- /**
- * Removes an item from the map by its key.
- * This overrides the parent implementation by converting the key to lower case first if {@link caseSensitive} is false.
- * @param {Mixed} key the key of the item to be removed
- * @returns {Mixed} the removed value, null if no such key exists.
- */
- Yii.CAttributeCollection.prototype.remove = function (key) {
- if(this.caseSensitive) {
- return Yii.CMap.prototype.remove.call(this, key);
- }
- else {
- return Yii.CMap.prototype.remove.call(this, key.toLowerCase());
- }
- };
- /**
- * Returns whether the specified is in the map.
- * This overrides the parent implementation by converting the key to lower case first if {@link caseSensitive} is false.
- * @param {Mixed} key the key
- * @returns {Boolean} whether the map contains an item with the specified key
- */
- Yii.CAttributeCollection.prototype.contains = function (key) {
- if(this.caseSensitive) {
- return Yii.CMap.prototype.contains.call(this, key);
- }
- else {
- return Yii.CMap.prototype.contains.call(this, key.toLowerCase());
- }
- };
- /**
- * Determines whether a property is defined.
- * This method overrides parent implementation by returning true
- * if the collection contains the named key.
- * @param {String} name the property name
- * @returns {Boolean} whether the property is defined
- */
- Yii.CAttributeCollection.prototype.hasProperty = function (name) {
- return this.contains(name) || Yii.CMap.prototype.hasProperty.call(this, name);
- };
- /**
- * Determines whether a property can be read.
- * This method overrides parent implementation by returning true
- * if the collection contains the named key.
- * @param {String} name the property name
- * @returns {Boolean} whether the property can be read
- */
- Yii.CAttributeCollection.prototype.canGetProperty = function (name) {
- return this.contains(name) || Yii.CMap.prototype.canGetProperty.call(this, name);
- };
- /**
- * Determines whether a property can be set.
- * This method overrides parent implementation by always returning true
- * because you can always add a new value to the collection.
- * @param {String} name the property name
- * @returns {Boolean} true
- */
- Yii.CAttributeCollection.prototype.canSetProperty = function (name) {
- return true;
- }/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CConfiguration represents an array-based configuration.
- *
- * It can be used to initialize an object's properties.
- *
- * The configuration data may be obtained from a PHP script. For example,
- * <pre>
- * return {
- * 'name':'My Application',
- * 'defaultController':'index',
- * };
- * </pre>
- * Use the following code to load the above configuration data:
- * <pre>
- * config=new Yii.CConfiguration('path/to/config.php');
- * </pre>
- *
- * To apply the configuration to an object, call {@link applyTo()}.
- * Each (key,value) pair in the configuration data is applied
- * to the object like: $object->$key=$value.
- *
- * Since CConfiguration extends from {@link CMap}, it can be
- * used like an associative array. See {@link CMap} for more details.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CConfiguration.php 3001 2011-02-24 16:42:44Z alexander.makarow $
- * @package system.collections
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CMap
- */
- Yii.CConfiguration = function CConfiguration (data, readOnly) {
- this.construct(data, readOnly);
-
- };
- Yii.CConfiguration.prototype = new Yii.CMap();
- Yii.CConfiguration.prototype.constructor = Yii.CConfiguration;
- /**
- * Saves the configuration into a JSON string.
- * The string is a valid JSON expression representing the configuration data as an object.
- * @returns {String} the JSON representation of the configuration
- */
- Yii.CConfiguration.prototype.saveAsString = function () {
- return Yii.CJSON.encode(this.toObject());
- };
- /**
- * Applies the configuration to an object.
- * Each (key,value) pair in the configuration data is applied
- * to the object like: $object->$key=$value.
- * @param {Object} object object to be applied with this configuration
- */
- Yii.CConfiguration.prototype.applyTo = function (object) {
- var keyValue, key, value;
- keyValue = this.toObject();
- for (key in keyValue) {
- if (keyValue.hasOwnProperty(key)) {
- value = keyValue[key];
- object[key] = value;
- }
- }
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CQueue implements a queue.
- *
- * The typical queue operations are implemented, which include
- * {@link enqueue()}, {@link dequeue()} and {@link peek()}. In addition,
- * {@link contains()} can be used to check if an item is contained
- * in the queue. To obtain the number of the items in the queue,
- * check the {@link getCount Count} property.
- *
- * Items in the queue may be traversed using foreach as follows,
- * <pre>
- * for (i in queue) +++
- * </pre>
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CQueue.php 3001 2011-02-24 16:42:44Z alexander.makarow $
- * @package system.collections
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CComponent
- */
- Yii.CQueue = function CQueue(data) {
- this.readOnly = false;
- this.construct(data);
-
- };
- Yii.CQueue.prototype = new Yii.CList();
- Yii.CQueue.prototype.constructor = Yii.CQueue;
- /**
- * Constructor.
- * Initializes the queue with an array or an iterable object.
- * @param {Array} data the intial data. Default is null, meaning no initialization.
- * @throws {Yii.CException} If data is not null and neither an array nor an iterator.
- */
- Yii.CQueue.prototype.construct = function (data) {
- if (data === undefined) {
- data = null;
- }
- if(data!==null) {
- this.copyFrom(data);
- }
- };
- /**
- * @param {Mixed} item the item
- * @returns {Boolean} whether the queue contains the item
- */
- Yii.CQueue.prototype.contains = function (item) {
- var i, limit = this.length;
- for (i = 0; i < limit; i++) {
- if (item === this[i]) {
- return true;
- }
- }
- return false;
- };
- /**
- * Returns the item at the top of the queue.
- * @returns {Mixed} item at the top of the queue
- * @throws {Yii.CException} if the queue is empty
- */
- Yii.CQueue.prototype.peek = function () {
- if(this.length===0) {
- throw new Yii.CException(Yii.t('yii','The queue is empty.'));
- }
- else {
- return this[0];
- }
- };
- /**
- * Removes and returns the object at the beginning of the queue.
- * @returns {Mixed} the item at the beginning of the queue
- * @throws {Yii.CException} if the queue is empty
- */
- Yii.CQueue.prototype.dequeue = function () {
- if(this.length===0) {
- throw new Yii.CException(Yii.t('yii','The queue is empty.'));
- }
- else {
- return this.shift();
- }
- };
- /**
- * Adds an object to the end of the queue.
- * @param {Mixed} item the item to be appended into the queue
- */
- Yii.CQueue.prototype.enqueue = function (item) {
- this.push(item);
- };
- /*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CStack implements a stack.
- *
- * The typical stack operations are implemented, which include
- * {@link push()}, {@link pop()} and {@link peek()}. In addition,
- * {@link contains()} can be used to check if an item is contained
- * in the stack. To obtain the number of the items in the stack,
- * check the {@link getCount Count} property.
- *
- * Items in the stack may be traversed using foreach as follows,
- * <pre>
- * for (i in stack) +++
- * </pre>
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CStack.php 3001 2011-02-24 16:42:44Z alexander.makarow $
- * @package system.collections
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CComponent
- */
- Yii.CStack = function CStack (data) {
- this.construct(data);
- };
- Yii.CStack.prototype = new Array();
- Yii.CStack.prototype.constructor = Yii.CStack;
- Yii.augment(Yii.CStack, Yii.CComponent);
- /**
- * Constructor.
- * Initializes the stack with an array or an iterable object.
- * @param {Array} data the initial data. Default is null, meaning no initialization.
- * @throws {Yii.CException} If data is not null and neither an array nor an iterator.
- */
- Yii.CStack.prototype.construct = function (data) {
- if (data === undefined) {
- data = null;
- }
- if(data!==null) {
- this.copyFrom(data);
- }
- };
- /**
- * @returns {Array} the list of items in stack
- */
- Yii.CStack.prototype.toArray = function () {
- var ret = [], i, limit;
- limit = this.length;
- for (i = 0; i < limit; i++) {
- ret.push(this[i]);
- }
- return ret;
- };
- /**
- * Copies iterable data into the stack.
- * Note, existing data in the list will be cleared first.
- * @param {Mixed} data the data to be copied from, must be an array or object implementing Traversable
- * @throws {Yii.CException} If data is neither an array nor a Traversable.
- */
- Yii.CStack.prototype.copyFrom = function (data) {
- var i, item;
- if(Object.prototype.toString.call(data) === '[object Array]' || (data instanceof Array))
- {
- this.clear();
- for (i in data)
- {
- if (data.hasOwnProperty(i)) {
- item = data[i];
- this.push(item);
- }
- }
- }
- else if(data!==null) {
- throw new Yii.CException(Yii.t('yii','Stack data must be an array or an object implementing Traversable.'));
- }
- };
- /**
- * Removes all items in the stack.
- */
- Yii.CStack.prototype.clear = function () {
- var i, limit;
- limit = this.length;
- for(i = 0; i < limit; i++) {
- delete this[i];
- }
- };
- /**
- * @param {Mixed} item the item
- * @returns {Boolean} whether the stack contains the item
- */
- Yii.CStack.prototype.contains = function (item) {
- var i, limit = this.length;
- for (i = 0; i < limit; i++) {
- if (item === this[i]) {
- return true;
- }
- }
- return false;
- };
- /**
- * Returns the item at the top of the stack.
- * Unlike {@link pop()}, this method does not remove the item from the stack.
- * @returns {Mixed} item at the top of the stack
- * @throws {Yii.CException} if the stack is empty
- */
- Yii.CStack.prototype.peek = function () {
- if(this.length) {
- return this[this.length - 1];
- }
- else {
- throw new Yii.CException(Yii.t('yii','The stack is empty.'));
- }
- };
- /**
- * Pops up the item at the top of the stack.
- * @returns {Mixed} the item at the top of the stack
- * @throws {Yii.CException} if the stack is empty
- */
- Yii.CStack.prototype.pop = function () {
- if(this.length) {
- return Array.prototype.pop.call(this);
- }
- else {
- throw new Yii.CException(Yii.t('yii','The stack is empty.'));
- }
- };
- /**
- * Returns the number of items in the stack.
- * @returns {Integer} the number of items in the stack
- */
- Yii.CStack.prototype.getCount = function () {
- return this.length;
- };
- /**
- * Returns the number of items in the stack.
- * This method is required by Countable interface.
- * @returns {Integer} number of items in the stack.
- */
- Yii.CStack.prototype.count = function () {
- return this.length;
- };
- /**
- * Provides convenient access to Yii.forEach()
- * @param {Function} callback The callback function, this will receive 2 parameters, key and value
- * @returns {Yii.CStack} the stack
- */
- Yii.CStack.prototype.forEach = function(callback) {
- return Yii.forEach(this,callback);
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CTypedList represents a list whose items are of the certain type.
- *
- * CTypedList extends {@link CList} by making sure that the elements to be
- * added to the list is of certain class type.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CTypedList.php 3001 2011-02-24 16:42:44Z alexander.makarow $
- * @package system.collections
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CList
- */
- Yii.CTypedList = function CTypedList (type) {
- this.construct(type);
- };
- Yii.CTypedList.prototype = new Yii.CList();
- Yii.CTypedList.prototype.constructor = Yii.CTypedList;
- Yii.CTypedList.prototype._type = null;
- /**
- * Constructor.
- * @param {String} type class type
- */
- Yii.CTypedList.prototype.construct = function (type) {
- this._type=type;
- };
- /**
- * Inserts an item at the specified position.
- * This method overrides the parent implementation by
- * checking the item to be inserted is of certain type.
- * @param {Integer} index the specified position.
- * @param {Mixed} item new item
- * @throws {Yii.CException} If the index specified exceeds the bound,
- * the list is read-only or the element is not of the expected type.
- */
- Yii.CTypedList.prototype.insertAt = function (index, item) {
- if(item instanceof this._type) {
- Yii.CList.prototype.insertAt.call(this,index,item);
- }
- else {
- throw new Yii.CException(Yii.t('yii','CTypedList<{type}> can only hold objects of {type} class.',
- {'{type}':this._type}));
- }
- };
- /**
- * Pushes an item on to the end of the list
- * @param {Mixed} the item to add
- * @returns {Integer} the number of items in the list
- */
- Yii.CTypedList.prototype.push = function (item) {
- if(item instanceof this._type) {
- return Yii.CList.prototype.push.call(this,item);
- }
- else {
- throw new Yii.CException(Yii.t('yii','CTypedList<{type}> can only hold objects of {type} class.',
- {'{type}':this._type}));
- }
- };
- /*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CTypedMap represents a map whose items are of the certain type.
- *
- * CTypedMap extends {@link CMap} by making sure that the elements to be
- * added to the list is of certain class type.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CTypedMap.php 3001 2011-02-24 16:42:44Z alexander.makarow $
- * @package system.collections
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CMap
- */
- Yii.CTypedMap = function CTypedMap (type) {
- this.construct(type);
- };
- Yii.CTypedMap.prototype = new Yii.CMap();
- Yii.CTypedMap.prototype.constructor = Yii.CTypedMap;
- Yii.CTypedMap.prototype._type = null;
- /**
- * Constructor.
- * @param {String} type class type
- */
- Yii.CTypedMap.prototype.construct = function (type) {
- this._type=type;
- };
- /**
- * Adds an item into the map.
- * This method overrides the parent implementation by
- * checking the item to be inserted is of certain type.
- * @param {Integer} index the specified position.
- * @param {Mixed} item new item
- * @throws {Yii.CException} If the index specified exceeds the bound,
- * the map is read-only or the element is not of the expected type.
- */
- Yii.CTypedMap.prototype.add = function (index, item) {
- if(item instanceof this._type) {
- Yii.CMap.prototype.add.call(this, index,item);
- }
- else {
- throw new Yii.CException(Yii.t('yii','CTypedMap<{type}> can only hold objects of {type} class.',
- {'{type}':this._type}));
- }
- };var YII_PATH = "/js/test/";
- var appConfig = {
- 'basePath': "/js/app",
- 'name': "EbayStore",
- 'preload': ["log"],
- 'params': {
- 'version': 0.1
- },
- 'components': {
- 'db': {
- 'connectionString': 'sqlite:host=localhost;dbname=ebaystore',
- 'enableParamLogging': true,
- 'enableProfiling': true,
- 'initSQLs': [
-
- ]
- },
- 'viewRenderer' : {
- 'class': 'CMustacheViewRenderer'
- },
- 'request': {
- 'enableCsrfValidation': true,
- 'enableCookieValidation': true
- },
- 'log': {
- 'class': 'CLogRouter',
- 'routes': [
- {
- 'class': 'CProfileLogRoute',
- 'showInFireBug': false
- },
- {
- 'class': 'CWebLogRoute',
- 'showInFireBug': false
- }
- ]
- },
- 'cache': {
- 'class': 'CSessionCache'
- },
- 'urlManager': {
- 'urlFormat': 'path',
- 'showScriptName': false,
- 'urlSuffix': '.html',
- 'useStrictParsing': false,
- 'rules': [
- {
- 'pattern': '/',
- 'route': '/site/index',
- 'urlSuffix': ''
- },
- {
- 'pattern': 'contactus',
- 'route': '/site/contact'
- },
- {
- 'pattern': '<controller:\\w+>s',
- 'route': '<controller>/index'
- },
- {
- 'pattern': '<controller:\\w+>s/<id:\\d+>',
- 'route': '<controller>/view'
- },
- {
- 'pattern': '<controller:\\w+>s/<action:\\w+>/<id:\\d+>',
- 'route': '<controller>/<action>'
- },
- {
- 'pattern': '<controller:\\w+>s/<action:\\w+>',
- 'route': '<controller>/<action>'
- }
- ]
- }
- }
- };
- /*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * A base class for data sources.
- * @package system.ds
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CComponent
- */
- Yii.CActiveDataSource = function CActiveDataSource () {
-
- };
- Yii.CActiveDataSource.prototype = new Yii.CComponent();
- Yii.CActiveDataSource.prototype.constructor = Yii.CActiveDataSource;
-
- /**
- * Gets data from the data source and executes the callback when data arrives.
- * Child classes must override this method!
- * @param {Function} callback The callback function to execute, this will recieve the
- * data as its first parameter and the data source as its second parameter.
- *
- */
- Yii.CActiveDataSource.prototype.getData = function (callback) {
-
- };
-
- /*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CAsyncRecord is the base class for classes representing relational data loaded from a remote data source.
- *
- * It implements the active record design pattern, a popular Object-Relational Mapping (ORM) technique.
- *
- * @package system.ds
- * @since 1.0
- *
- * @property array $attributes
- * @author Charles Pick
- * @class
- * @extends Yii.CModel
- */
- Yii.CAsyncRecord = function CAsyncRecord (scenario, callback) {
- if (scenario !== false) {
- return this.construct(scenario, callback);
- }
- };
- Yii.CAsyncRecord.prototype = new Yii.CModel(false);
- Yii.CAsyncRecord.prototype.constructor = Yii.CAsyncRecord;
- /**
- * @const
- */
- Yii.CAsyncRecord.prototype.BELONGS_TO = 'CBelongsToRelation';
- /**
- * @const
- */
- Yii.CAsyncRecord.prototype.HAS_ONE = 'CHasOneRelation';
- /**
- * @const
- */
- Yii.CAsyncRecord.prototype.HAS_MANY = 'CHasManyRelation';
- /**
- * @const
- */
- Yii.CAsyncRecord.prototype.MANY_MANY = 'CManyManyRelation';
- /**
- * @const
- */
- Yii.CAsyncRecord.prototype.STAT = 'CStatRelation';
- /**
- * @var {Yii.CActiveDataSource} the default data source for all active records
- * @see getDbConnection
- */
- Yii.CAsyncRecord.prototype._ds = null;
- /**
- * Whether or not to wrap the posted data in an object or not.
- * If this is set to true, data will be wrapped in an object with the same name as
- * this model. If set to a string, the string value will be used to wrap. If false
- * no wrapping will be applied.
- * Defaults to false.
- * @var Mixed
- */
- Yii.CAsyncRecord.prototype.wrapData = false;
- Yii.CAsyncRecord.prototype._models = {};
- Yii.CAsyncRecord.prototype._new = false;
- Yii.CAsyncRecord.prototype._attributes = {};
- Yii.CAsyncRecord.prototype._related = {};
- Yii.CAsyncRecord.prototype._c = null;
- Yii.CAsyncRecord.prototype._pk = null;
- Yii.CAsyncRecord.prototype._alias = 't';
- /**
- * Constructor.
- * @param {String} scenario scenario name. See {@link CModel::scenario} for more details about this parameter.
- */
- Yii.CAsyncRecord.prototype.construct = function (scenario) {
- if (scenario === undefined) {
- scenario = 'insert';
- }
- if(scenario===null) { // internally used by populateRecord() and model()
- return;
- }
- this._attributes = {};
- this._ds = this.dataStoreDefaults();
- this.setScenario(scenario);
- this.setIsNewRecord(true);
- this._attributes=this.attributeDefaults();
- this.init();
- this.attachBehaviors(this.behaviors());
- this.afterConstruct();
- };
-
- /**
- * Initializes this model.
- * This method is invoked when an AR instance is newly created and has
- * its {@link scenario} set.
- * You may override this method to provide code that is needed to initialize the model (e.g. setting
- * initial property values.)
- * @since 1.0.8
- */
- Yii.CAsyncRecord.prototype.init = function () {
- };
- /**
- * Returns a list of attribute names and their default values.
- * Child classes should override this!
- * @returns {Object} attributeName: value
- */
- Yii.CAsyncRecord.prototype.attributeDefaults = function () {
- return {};
- };
- /**
- * Sets the parameters about query caching.
- * This is a shortcut method to {@link CDbConnection::cache()}.
- * It changes the query caching parameter of the {@link dbConnection} instance.
- * @param {Integer} duration the number of seconds that query results may remain valid in cache.
- * If this is 0, the caching will be disabled.
- * @param {Yii.CCacheDependency} dependency the dependency that will be used when saving the query results into cache.
- * @param {Integer} queryCount number of SQL queries that need to be cached after calling this method. Defaults to 1,
- * meaning that the next SQL query will be cached.
- * @returns {Yii.CAsyncRecord} the active record instance itself.
- * @since 1.1.7
- */
- Yii.CAsyncRecord.prototype.cache = function (duration, dependency, queryCount) {
- if (dependency === undefined) {
- dependency = null;
- }
- if (queryCount === undefined) {
- queryCount = 1;
- }
- this.getDataSource().cache(duration, dependency, queryCount);
- return this;
- };
-
- /**
- * Getter magic method.
- * This method is overridden so that RR attributes can be accessed like properties.
- * @param {String} name property name
- * @returns {Mixed} property value
- * @see getAttribute
- */
- Yii.CAsyncRecord.prototype.get = function (name) {
- var getter, i, object, nameParts = [], limit;
- if (name.indexOf(".") !== -1) {
- nameParts = name.split(".");
- name = nameParts.shift();
- }
- if (this[name] !== undefined) {
- object = this[name];
- }
- else if (this._attributes[name] !== undefined) {
- object = this._attributes[name];
- }
- else if (this._related[name] !== undefined) {
- object = this._related[name];
- }
- if (object !== undefined) {
- if (nameParts.length > 0) {
- if (object instanceof Yii.CComponent) {
- return object.get(nameParts.join("."));
- }
- limit = nameParts.length;
- for (i = 0; i < limit; i++) {
- name = nameParts.shift();
- object = object[name];
- if (nameParts.length === 0) {
- return object;
- }
-
- if (object instanceof Yii.CComponent) {
- return object.get(nameParts.join("."));
- }
- }
- }
- return object;
- }
- else {
- if (nameParts.length > 0) {
- return Yii.CModel.prototype.get.call(this, php.array_merge([name],nameParts).join("."));
- }
- return Yii.CModel.prototype.get.call(this,name);
- }
- };
- /**
- * Setter magic method.
- * This method is overridden so that RR attributes can be accessed like properties.
- * @param {String} name property name
- * @param {Mixed} value property value
- */
- Yii.CAsyncRecord.prototype.set = function (name, value) {
- var nameParts = [];
- if (name.indexOf(".") !== -1) {
- nameParts = name.split(".");
- name = nameParts.pop();
- nameParts = nameParts.join(".");
- return (this.get(nameParts)[name] = value);
- }
- else if(this.setAttribute(name,value)===false) {
- if(this.relations[name] !== undefined) {
- this._related[name]=value;
- }
- else {
- Yii.CModel.prototype.set.call(this, name,value);
- }
- }
- };
- /**
- * Gets the data source for this model.
- * @returns {Yii.CActiveDataSource} The data source that this model interacts with
- */
- Yii.CAsyncRecord.prototype.getDataSource = function () {
- if (this._ds !== null) {
- if (this._ds instanceof Yii.CActiveDataSource) {
- return this._ds;
- }
- this._ds = Yii.createComponent(this._ds);
- }
- return this._ds;
- };
-
- /**
- * Sets the data source for this model
- * @param {Yii.CActiveDataSource} value The data source to use with this model
- */
- Yii.CAsyncRecord.prototype.setDataSource = function (value) {
- var className;
- if (!(value instanceof Yii.CActiveDataSource)) {
- if (value['class'] !== undefined) {
- className = value['class'];
- delete value['class'];
- }
- else {
- className = 'CActiveDataSource';
- }
-
- value = Yii.createComponent(className, value);
- }
- this._ds = value;
- }
-
- /**
- * Checks whether this AR has the named attribute
- * @param {String} name attribute name
- * @returns {Boolean} whether this AR has the named attribute (table column).
- */
- Yii.CAsyncRecord.prototype.hasAttribute = function (name) {
- return this.get(name) !== undefined;
- };
- /**
- * Returns the named attribute value.
- * If this is a new record and the attribute is not set before,
- * the default column value will be returned.
- * If this record is the result of a query and the attribute is not loaded,
- * null will be returned.
- * You may also use $this->AttributeName to obtain the attribute value.
- * @param {String} name the attribute name
- * @returns {Mixed} the attribute value. Null if the attribute is not set or does not exist.
- * @see hasAttribute
- */
- Yii.CAsyncRecord.prototype.getAttribute = function (name) {
- if(this[name] !== undefined) {
- return this[name];
- }
- else if(this._attributes[name] !== undefined) {
- return this._attributes[name];
- }
- };
- /**
- * Returns all column attribute values.
- * Note, related objects are not returned.
- * @param {Mixed} names names of attributes whose value needs to be returned.
- * If this is true (default), then all attribute values will be returned, including
- * those that are not loaded from DB (null will be returned for those attributes).
- * If this is null, all attributes except those that are not loaded from DB will be returned.
- * @returns {Array} attribute values indexed by attribute names.
- */
- Yii.CAsyncRecord.prototype.getAttributes = function (names) {
- var attributes, nameColumn, name, attrs, i, column;
- if (names === undefined) {
- names = true;
- }
- attributes=this._attributes;
-
- if(Object.prototype.toString.call(names) === '[object Array]') {
- attrs=[];
- for (i in names) {
- if (names.hasOwnProperty(i)) {
- name = names[i];
- if(this[name] !== undefined) {
- attrs[name]=this.name;
- }
- else {
- attrs[name]=attributes[name] !== undefined?attributes[name]:null;
- }
- }
- }
- return attrs;
- }
- else {
- return attributes;
- }
- };
- /**
- * Sets the named attribute value.
- * You may also use $this->AttributeName to set the attribute value.
- * @param {String} name the attribute name
- * @param {Mixed} value the attribute value.
- * @returns {Boolean} whether the attribute exists and the assignment is conducted successfully
- * @see hasAttribute
- */
- Yii.CAsyncRecord.prototype.setAttribute = function (name, value) {
- if(this[name] !== undefined) {
- this[name]=value;
- }
- else if(this._attributes[name] !== undefined) {
- this._attributes[name]=value;
- }
- else {
- return false;
- }
- return true;
- };
-
- /**
- * Returns if the current record is new.
- * @returns {Boolean} whether the record is new and should be inserted when calling {@link save}.
- * This property is automatically set in constructor and {@link populateRecord}.
- * Defaults to false, but it will be set to true if the instance is created using
- * the new operator.
- */
- Yii.CAsyncRecord.prototype.getIsNewRecord = function () {
- return this._new;
- };
- /**
- * Sets if the record is new.
- * @param {Boolean} value whether the record is new and should be inserted when calling {@link save}.
- * @see getIsNewRecord
- */
- Yii.CAsyncRecord.prototype.setIsNewRecord = function (value) {
- this._new=value;
- };
- /**
- * This event is raised before the record is saved.
- * By setting {@link CModelEvent::isValid} to be false, the normal {@link save()} process will be stopped.
- * @param {Yii.CModelEvent} event the event parameter
- * @since 1.0.2
- */
- Yii.CAsyncRecord.prototype.onBeforeSave = function (event) {
- this.raiseEvent('onBeforeSave',event);
- };
- /**
- * This event is raised after the record is saved.
- * @param {Yii.CEvent} event the event parameter
- * @since 1.0.2
- */
- Yii.CAsyncRecord.prototype.onAfterSave = function (event) {
- this.raiseEvent('onAfterSave',event);
- };
- /**
- * This event is raised before the record is deleted.
- * By setting {@link CModelEvent::isValid} to be false, the normal {@link delete()} process will be stopped.
- * @param {Yii.CModelEvent} event the event parameter
- * @since 1.0.2
- */
- Yii.CAsyncRecord.prototype.onBeforeDelete = function (event) {
- this.raiseEvent('onBeforeDelete',event);
- };
- /**
- * This event is raised after the record is deleted.
- * @param {Yii.CEvent} event the event parameter
- * @since 1.0.2
- */
- Yii.CAsyncRecord.prototype.onAfterDelete = function (event) {
- this.raiseEvent('onAfterDelete',event);
- };
- /**
- * This event is raised before an AR finder performs a find call.
- * In this event, the {@link CModelEvent::criteria} property contains the query criteria
- * passed as parameters to those find methods. If you want to access
- * the query criteria specified in scopes, please use {@link getDbCriteria()}.
- * You can modify either criteria to customize them based on needs.
- * @param {Yii.CModelEvent} event the event parameter
- * @see beforeFind
- * @since 1.0.9
- */
- Yii.CAsyncRecord.prototype.onBeforeFind = function (event) {
- this.raiseEvent('onBeforeFind',event);
- };
- /**
- * This event is raised after the record is instantiated by a find method.
- * @param {Yii.CEvent} event the event parameter
- * @since 1.0.2
- */
- Yii.CAsyncRecord.prototype.onAfterFind = function (event) {
- this.raiseEvent('onAfterFind',event);
- };
- /**
- * This method is invoked before saving a record (after validation, if any).
- * The default implementation raises the {@link onBeforeSave} event.
- * You may override this method to do any preparation work for record saving.
- * Use {@link isNewRecord} to determine whether the saving is
- * for inserting or updating record.
- * Make sure you call the parent implementation so that the event is raised properly.
- * @returns {Boolean} whether the saving should be executed. Defaults to true.
- */
- Yii.CAsyncRecord.prototype.beforeSave = function () {
- var event;
- if(this.hasEventHandler('onBeforeSave')) {
- event=new Yii.CModelEvent(this);
- this.onBeforeSave(event);
- return event.isValid;
- }
- else {
- return true;
- }
- };
- /**
- * This method is invoked after saving a record successfully.
- * The default implementation raises the {@link onAfterSave} event.
- * You may override this method to do postprocessing after record saving.
- * Make sure you call the parent implementation so that the event is raised properly.
- */
- Yii.CAsyncRecord.prototype.afterSave = function () {
- if(this.hasEventHandler('onAfterSave')) {
- this.onAfterSave(new Yii.CEvent(this));
- }
- };
- /**
- * This method is invoked before deleting a record.
- * The default implementation raises the {@link onBeforeDelete} event.
- * You may override this method to do any preparation work for record deletion.
- * Make sure you call the parent implementation so that the event is raised properly.
- * @returns {Boolean} whether the record should be deleted. Defaults to true.
- */
- Yii.CAsyncRecord.prototype.beforeDelete = function () {
- var event;
- if(this.hasEventHandler('onBeforeDelete')) {
- event=new Yii.CModelEvent(this);
- this.onBeforeDelete(event);
- return event.isValid;
- }
- else {
- return true;
- }
- };
- /**
- * This method is invoked after deleting a record.
- * The default implementation raises the {@link onAfterDelete} event.
- * You may override this method to do postprocessing after the record is deleted.
- * Make sure you call the parent implementation so that the event is raised properly.
- */
- Yii.CAsyncRecord.prototype.afterDelete = function () {
- if(this.hasEventHandler('onAfterDelete')) {
- this.onAfterDelete(new Yii.CEvent(this));
- }
- };
- /**
- * This method is invoked before an AR finder executes a find call.
- * The find calls include {@link find}, {@link findAll}, {@link findByPk},
- * {@link findAllByPk}, {@link findByAttributes} and {@link findAllByAttributes}.
- * The default implementation raises the {@link onBeforeFind} event.
- * If you override this method, make sure you call the parent implementation
- * so that the event is raised properly.
- *
- * Starting from version 1.1.5, this method may be called with a hidden {@link CDbCriteria}
- * parameter which represents the current query criteria as passed to a find method of AR.
- *
- * @since 1.0.9
- */
- Yii.CAsyncRecord.prototype.beforeFind = function () {
- var event;
- if(this.hasEventHandler('onBeforeFind')) {
- event=new Yii.CModelEvent(this);
- // for backward compatibility
- event.criteria=arguments.length>0 ? arguments[0] : null;
- this.onBeforeFind(event);
- }
- };
- /**
- * This method is invoked after each record is instantiated by a find method.
- * The default implementation raises the {@link onAfterFind} event.
- * You may override this method to do postprocessing after each newly found record is instantiated.
- * Make sure you call the parent implementation so that the event is raised properly.
- */
- Yii.CAsyncRecord.prototype.afterFind = function () {
- if(this.hasEventHandler('onAfterFind')) {
- this.onAfterFind(new Yii.CEvent(this));
- }
- };
- /**
- * Calls {@link beforeFind}.
- * This method is internally used.
- * @since 1.0.11
- */
- Yii.CAsyncRecord.prototype.beforeFindInternal = function () {
- this.beforeFind();
- };
- /**
- * Calls {@link afterFind}.
- * This method is internally used.
- * @since 1.0.3
- */
- Yii.CAsyncRecord.prototype.afterFindInternal = function () {
- this.afterFind();
- };
-
-
- /**
- * Adds an item to the data source based on this remote record attributes.
- * Note, validation is not performed in this method. You may call {@link validate} to perform the validation.
- * After the record is inserted to data source successfully, its {@link isNewRecord} property will be set false,
- * and its {@link scenario} property will be set to be 'update'.
- * @param {Array} attributes list of attributes that need to be saved. Defaults to null,
- * meaning all attributes that are loaded from DS will be saved.
- * @param {Function} callback The callback that will be executed after the insert succeeds
- * @returns {Mixed} The data source request
- * @throws {Yii.CException} if the record is not new
- */
- Yii.CAsyncRecord.prototype.create = function (attributes, callback) {
- var builder, table, command, primaryKey, i, pk, self = this, func, postData;
- if (attributes === undefined) {
- attributes = null;
- }
- if(!this.getIsNewRecord()) {
- throw new Yii.CDbException(Yii.t('yii','The remote record cannot be created because it is not new.'));
- }
- if(this.beforeSave()) {
- Yii.trace(this.getClassName()+'.create()','system.ds.CAsyncRecord');
- func = function (data, dataSource) {
- var model;
- model = self.populateRecord(data);
- model.afterSave();
- model.setIsNewRecord(false);
- model.setScenario('update');
- callback(model, dataSource);
- };
- if (this.wrapData === true) {
- postData = {};
- postData[this.getClassName()] = this.getAttributes(attributes);
- }
- else if (this.wrapData) {
- postData = {};
- postData[this.wrapData] = this.getAttributes(attributes);
- }
- else {
- postData = this.getAttributes(attributes);
- }
- return this.getDataSource().create(postData, func);
- }
- return false;
- };
- /**
- * Updates the row represented by this remote record.
- * All loaded attributes will be saved to the database.
- * Note, validation is not performed in this method. You may call {@link validate} to perform the validation.
- * @param {Array} attributes list of attributes that need to be saved. Defaults to null,
- * meaning all attributes that are loaded from DB will be saved.
- * @param {Function} callback The callback that will be executed after the update succeeds
- * @returns {Mixed} The data source request
- * @throws {Yii.CException} if the record is new
- */
- Yii.CAsyncRecord.prototype.update = function (attributes, callback) {
- var self = this, func, postData;
- if (attributes === undefined) {
- attributes = null;
- }
- if(this.getIsNewRecord()) {
- throw new Yii.CDbException(Yii.t('yii','The remote record cannot be updated because it is new.'));
- }
-
- if(this.beforeSave()) {
- Yii.trace(this.getClassName()+'.update()','system.ds.CAsyncRecord');
- func = function (data, dataSource) {
- var model;
- model = self.populateRecord(data);
- model.afterSave();
- model.setIsNewRecord(false);
- model.setScenario('update');
- callback(model, dataSource);
- };
- if (this.wrapData === true) {
- postData = {};
- postData[this.getClassName()] = this.getAttributes(attributes);
- }
- else if (this.wrapData) {
- postData = {};
- postData[this.wrapData] = this.getAttributes(attributes);
- }
- else {
- postData = this.getAttributes(attributes);
- }
-
- return this.getDataSource().update(postData, func);
- }
- else {
- return false;
- }
- };
- /**
- * Saves a selected list of attributes.
- * Unlike {@link save}, this method only saves the specified attributes
- * of an existing row dataset and does NOT call either {@link beforeSave} or {@link afterSave}.
- * Also note that this method does neither attribute filtering nor validation.
- * So do not use this method with untrusted data (such as user posted data).
- * @param {Array} attributes attributes to be updated. Each element represents an attribute name
- * or an attribute value indexed by its name. If the latter, the record's
- * attribute will be changed accordingly before saving.
- * @param {Function} callback The callback that will be executed after the insert succeeds
- * @returns {Mixed} The data source request
- * @throws {Yii.CException} if the record is new or any database error
- */
- Yii.CAsyncRecord.prototype.saveAttributes = function (attributes, callback) {
- var values, name, value;
- if(!this.getIsNewRecord()) {
- Yii.trace(this.getClassName()+'.saveAttributes()','system.ds.CAsyncRecord');
- values={};
- for (name in attributes) {
- if (attributes.hasOwnProperty(name)) {
- value = attributes[name];
- if((typeof(name) === 'number' && (name % 1 ? false : true))) {
- values[value]=this[value];
- }
- else {
- values[name]=this[name]=value;
- }
- }
- }
- Yii.trace(this.getClassName()+'.update()','system.ds.CAsyncRecord');
- return this.getDataSource().update(values, callback);
- }
- else {
- throw new Yii.CDbException(Yii.t('yii','The active record cannot be updated because it is new.'));
- }
- };
- /**
- * Saves the current record.
- *
- * The record is created if its {@link isNewRecord}
- * property is true (usually the case when the record is created using the 'new'
- * operator). Otherwise, it will be used to update the corresponding item in the data source
- * (usually the case if the record is obtained using one of those 'find' methods.)
- *
- * Validation will be performed before saving the record. If the validation fails,
- * the record will not be saved. You can call {@link getErrors()} to retrieve the
- * validation errors.
- *
- * If the record is saved via insertion, its {@link isNewRecord} property will be
- * set false, and its {@link scenario} property will be set to be 'update'.
- * And if its primary key is auto-incremental and is not set before insertion,
- * the primary key will be populated with the automatically generated key value.
- * @param {Function} callback The callback function that will be executed after the save
- * @param {Boolean} runValidation whether to perform validation before saving the record.
- * If the validation fails, the record will not be saved to database.
- * @param {Array} attributes list of attributes that need to be saved. Defaults to null,
- * meaning all attributes that are loaded from DB will be saved.
- * @returns {Mixed} the response from the data source
- */
- Yii.CAsyncRecord.prototype.save = function (callback, runValidation, attributes) {
- if (runValidation === undefined) {
- runValidation = true;
- }
- if (attributes === undefined) {
- attributes = null;
- }
- if(!runValidation || this.validate(attributes)) {
-
- return this.getIsNewRecord() ? this.create(attributes, callback) : this.update(attributes, callback);
- }
- else {
- return false;
- }
- };
-
- /**
- * Creates a remote record with the given attributes.
- * This method is internally used by the find methods.
- * @param {Array} attributes attribute values (column name=>column value)
- * @param {Boolean} callAfterFind whether to call {@link afterFind} after the record is populated.
- * This parameter is added in version 1.0.3.
- * @returns {Yii.CAsyncRecord} the newly created active record. The class of the object is the same as the model class.
- * Null is returned if the input data is false.
- */
- Yii.CAsyncRecord.prototype.populateRecord = function (attributes, callAfterFind) {
- var record, md, name, value;
- if (callAfterFind === undefined) {
- callAfterFind = true;
- }
- if(attributes!==false) {
- record=this.instantiate(attributes);
- record.setIsNewRecord(false);
- record.setScenario('update');
- record.init();
-
- for (name in attributes) {
- if (attributes.hasOwnProperty(name)) {
- value = attributes[name];
- if(record[name] !== undefined) {
- record[name]=value;
- }
- else if(record._attributes[name] !== undefined) {
- record._attributes[name]=value;
- }
- }
- }
- record._pk=record.getPrimaryKey();
- record.attachBehaviors(record.behaviors());
- if(callAfterFind) {
- record.afterFind();
- }
- return record;
- }
- else {
- return null;
- }
- };
- /**
- * Creates a list of active records based on the input data.
- * This method is internally used by the find methods.
- * @param {Array} data list of attribute values for the active records.
- * @param {Boolean} callAfterFind whether to call {@link afterFind} after each record is populated.
- * This parameter is added in version 1.0.3.
- * @param {String} index the name of the attribute whose value will be used as indexes of the query result array.
- * If null, it means the array will be indexed by zero-based integers.
- * @returns {Array} list of active records.
- */
- Yii.CAsyncRecord.prototype.populateRecords = function (data, callAfterFind, index) {
- var records, i, limit, record, attributes;
- if (callAfterFind === undefined) {
- callAfterFind = true;
- }
- if (index === undefined) {
- index = null;
- }
- records=[];
- limit = data.length;
- for (i = 0; i < limit; i++) {
- attributes = data[i];
- if((record=this.populateRecord(attributes,callAfterFind))!==null) {
- if(index===null) {
- records.push(record);
- }
- else {
- records[record[index]]=record;
- }
- }
- }
- return records;
- };
- /**
- * Creates an active record instance.
- * This method is called by {@link populateRecord} and {@link populateRecords}.
- * You may override this method if the instance being created
- * depends the attributes that are to be populated to the record.
- * For example, by creating a record based on the value of a column,
- * you may implement the so-called single-table inheritance mapping.
- * @param {Object} attributes list of attribute values for the active records.
- * @returns {Yii.CAsyncRecord} the active record
- * @since 1.0.2
- */
- Yii.CAsyncRecord.prototype.instantiate = function (attributes) {
- var classVar, model;
- classVar=this.getClassName();
- model=new Yii[classVar]();
- return model;
- };
-
- /**
- * Returns the primary key value.
- * @returns {Mixed} the primary key value. An array (column name=>column value) is returned if the primary key is composite.
- * If primary key is not defined, null will be returned.
- */
- Yii.CAsyncRecord.prototype.getPrimaryKey = function () {
- var table, values,name,pk,self = this;
- pk = this.primaryKey();
-
- if(typeof(pk) === 'string') {
-
- return this.get(pk);
- }
- else if(Object.prototype.toString.call(pk) === '[object Array]') {
- values={};
- Yii.forEach(pk, function (i, name) {
- values[name] = self.get(name);
- });
- return values;
- }
- else {
- return null;
- }
- };
- /**
- * Sets the primary key value.
- * After calling this method, the old primary key value can be obtained from {@link oldPrimaryKey}.
- * @param {Mixed} value the new primary key value. If the primary key is composite, the new value
- * should be provided as an array (column name=>column value).
- * @since 1.1.0
- */
- Yii.CAsyncRecord.prototype.setPrimaryKey = function (value) {
- var table, values,name,pk,self = this;
- pk = this.primaryKey();
- if(typeof(pk) === 'string') {
- this.set(pk, value);
- }
- else if(Object.prototype.toString.call(pk) === '[object Array]') {
- values={};
- Yii.forEach(pk, function (i, name) {
- self[name] = value[i];
- });
-
- }
-
- };
- /**
- * Performs a query, this is mainly used internally by the find / findAll methods
- * @param {Function} callback The callback function to execute when data arrives
- * @param {Object} criteria The criteria that will be sent to the server
- * @param {Boolean} all whether to return all data or not
- */
- Yii.CAsyncRecord.prototype.query = function (callback, criteria, all) {
- var command, finder, func, self = this;
- if (all === undefined) {
- all = false;
- }
- this.beforeFind();
- func = function(data, dataSource) {
- if (all) {
- return callback(self.populateRecords(data, true), dataSource);
- }
- else {
- return callback(self.populateRecord(data.shift(), true), dataSource);
- }
- };
- return this.getDataSource().search(criteria,func);
- };
-
-
- /**
- * Finds a single remote record with the specified condition.
- * @param {Function} callback The callback function that will recieve the results
- * @param {Mixed} criteria query criteria.
- * @returns {Yii.CAsyncRecord} the record found. Null if no record is found.
- */
- Yii.CAsyncRecord.prototype.find = function (callback, criteria) {
-
- Yii.trace(this.getClassName()+'.find()','system.ds.CAsyncRecord');
-
- return this.query(callback, criteria);
- };
- /**
- * Finds all remote records satisfying the specified condition.
- * See {@link find()} for detailed explanation about $condition and $params.
- * @param {Function} callback The callback function that will recieve the results
- * @param {Mixed} criteria query criteria.
- * @returns {Array} list of active records satisfying the specified condition. An empty array is returned if none is found.
- */
- Yii.CAsyncRecord.prototype.findAll = function (callback, criteria) {
- Yii.trace(this.getClassName()+'.findAll()','system.ds.CAsyncRecord');
- return this.query(callback, criteria,true);
-
- };
- /**
- * Finds a remote active record with the specified primary key.
- * See {@link find()} for detailed explanation about $condition and $params.
- * @param {Function} callback The callback function that will recieve the results
- * @param {Mixed} pk primary key value(s). Use array for multiple primary keys. For composite key, each key value must be an array (column name=>column value).
- * @returns {Yii.CAsyncRecord} the record found. Null if none is found.
- */
- Yii.CAsyncRecord.prototype.findByPk = function (callback, pk, criteria) {
- var postData;
- if (criteria === undefined) {
- criteria = {};
- }
- criteria[this.primaryKey()] = pk;
- if (this.wrapData === true) {
- postData = {};
- postData[this.getClassName()] = criteria;
- }
- else if (this.wrapData) {
- postData = {};
- postData[this.wrapData] = criteria;
- }
- else {
- postData = criteria;
- }
- Yii.trace(this.getClassName()+'.findByPk()','system.ds.CAsyncRecord');
-
-
- return this.query(callback, postData);
- };
- /**
- * Finds all active records with the specified primary keys.
- * See {@link find()} for detailed explanation about $condition and $params.
- * @param {Function} callback The callback function that will recieve the results
- * @param {Mixed} pk primary key value(s). Use array for multiple primary keys. For composite key, each key value must be an array (column name=>column value).
- * @param {Mixed} condition query condition or criteria.
- * @param {Object} params parameters to be bound to an SQL statement.
- * @returns {Array} the records found. An empty array is returned if none is found.
- */
- Yii.CAsyncRecord.prototype.findAllByPk = function (callback, pk, criteria) {
- var postData;
- if (criteria === undefined) {
- criteria = {};
- }
- criteria[this.primaryKey()] = pk;
- if (this.wrapData === true) {
- postData = {};
- postData[this.getClassName()] = criteria;
- }
- else if (this.wrapData) {
- postData = {};
- postData[this.wrapData] = criteria;
- }
- else {
- postData = criteria;
- }
- Yii.trace(this.getClassName()+'.findAllByPk()','system.ds.CAsyncRecord');
- return this.query(callback, postData,true);
- };
- /**
- * Finds a single active record that has the specified attribute values.
- * See {@link find()} for detailed explanation about $condition and $params.
- * @param {Function} callback The callback function that will recieve the results
- * @param {Object} attributes list of attribute values (indexed by attribute names) that the active records should match.
- * Since version 1.0.8, an attribute value can be an array which will be used to generate an IN condition.
- * @returns {Yii.CAsyncRecord} the record found. Null if none is found.
- */
- Yii.CAsyncRecord.prototype.findByAttributes = function (callback, attributes) {
- var postData;
- Yii.trace(this.getClassName()+'.findByAttributes()','system.ds.CAsyncRecord');
-
- if (this.wrapData === true) {
- postData = {};
- postData[this.getClassName()] = attributes;
- }
- else if (this.wrapData) {
- postData = {};
- postData[this.wrapData] = attributes;
- }
- else {
- postData = attributes;
- }
- return this.query(callback, postData);
- };
- /**
- * Finds all active records that have the specified attribute values.
- * See {@link find()} for detailed explanation about $condition and $params.
- * @param {Function} callback The callback function that will recieve the results
- * @param {Array} attributes list of attribute values (indexed by attribute names) that the active records should match.
- * Since version 1.0.8, an attribute value can be an array which will be used to generate an IN condition.
- * @returns {Array} the records found. An empty array is returned if none is found.
- */
- Yii.CAsyncRecord.prototype.findAllByAttributes = function (callback, attributes) {
- var postData;
- Yii.trace(this.getClassName()+'.findAllByAttributes()','system.ds.CAsyncRecord');
- if (this.wrapData === true) {
- postData = {};
- postData[this.getClassName()] = attributes;
- }
- else if (this.wrapData) {
- postData = {};
- postData[this.wrapData] = attributes;
- }
- else {
- postData = attributes;
- }
- return this.query(callback, postData, true);
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CAsyncRecordBehavior is the base class for behaviors that can be attached to {@link CAsyncRecord}.
- * Compared with {@link CModelBehavior}, CAsyncRecordBehavior attaches to more events
- * that are only defined by {@link CAsyncRecord}.
- *
- * @package system.ds
- * @since 1.0.2
- * @author Charles Pick
- * @class
- * @extends Yii.CModelBehavior
- */
- Yii.CAsyncRecordBehavior = function CAsyncRecordBehavior () {
- };
- Yii.CAsyncRecordBehavior.prototype = new Yii.CModelBehavior();
- Yii.CAsyncRecordBehavior.prototype.constructor = Yii.CAsyncRecordBehavior;
- /**
- * Declares events and the corresponding event handler methods.
- * If you override this method, make sure you merge the parent result to the return value.
- * @returns {Array} events (array keys) and the corresponding event handler methods (array values).
- * @see CBehavior::events
- */
- Yii.CAsyncRecordBehavior.prototype.events = function () {
- return php.array_merge(parent.events(), {
- 'onBeforeSave':'beforeSave',
- 'onAfterSave':'afterSave',
- 'onBeforeDelete':'beforeDelete',
- 'onAfterDelete':'afterDelete',
- 'onBeforeFind':'beforeFind',
- 'onAfterFind':'afterFind'
- });
- };
- /**
- * Responds to {@link CAsyncRecord::onBeforeSave} event.
- * Overrides this method if you want to handle the corresponding event of the {@link CBehavior::owner owner}.
- * You may set {@link CModelEvent::isValid} to be false to quit the saving process.
- * @param {Yii.CModelEvent} event event parameter
- */
- Yii.CAsyncRecordBehavior.prototype.beforeSave = function (event) {
- };
- /**
- * Responds to {@link CAsyncRecord::onAfterSave} event.
- * Overrides this method if you want to handle the corresponding event of the {@link CBehavior::owner owner}.
- * @param {Yii.CModelEvent} event event parameter
- */
- Yii.CAsyncRecordBehavior.prototype.afterSave = function (event) {
- };
- /**
- * Responds to {@link CAsyncRecord::onBeforeDelete} event.
- * Overrides this method if you want to handle the corresponding event of the {@link CBehavior::owner owner}.
- * You may set {@link CModelEvent::isValid} to be false to quit the deletion process.
- * @param {Yii.CEvent} event event parameter
- */
- Yii.CAsyncRecordBehavior.prototype.beforeDelete = function (event) {
- };
- /**
- * Responds to {@link CAsyncRecord::onAfterDelete} event.
- * Overrides this method if you want to handle the corresponding event of the {@link CBehavior::owner owner}.
- * @param {Yii.CEvent} event event parameter
- */
- Yii.CAsyncRecordBehavior.prototype.afterDelete = function (event) {
- };
- /**
- * Responds to {@link CAsyncRecord::onBeforeFind} event.
- * Overrides this method if you want to handle the corresponding event of the {@link CBehavior::owner owner}.
- * @param {Yii.CEvent} event event parameter
- * @since 1.0.9
- */
- Yii.CAsyncRecordBehavior.prototype.beforeFind = function (event) {
- };
- /**
- * Responds to {@link CAsyncRecord::onAfterFind} event.
- * Overrides this method if you want to handle the corresponding event of the {@link CBehavior::owner owner}.
- * @param {Yii.CEvent} event event parameter
- */
- Yii.CAsyncRecordBehavior.prototype.afterFind = function (event) {
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * A class for retrieving data from JSON data sources
- * @package system.ds
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CActiveDataSource
- */
- Yii.CJSONDataSource = function CJSONDataSource (construct) {
- if (construct !== false) {
- this.ajaxOptions = {};
- this.cacheDuration = null;
- this.cacheDependency = null;
- this.cacheKey = null;
- }
- };
- Yii.CJSONDataSource.prototype = new Yii.CActiveDataSource();
- Yii.CJSONDataSource.prototype.constructor = Yii.CJSONDataSource;
- Yii.CJSONDataSource.prototype.cacheDependency = null;
- Yii.CJSONDataSource.prototype.cacheDuration = null;
- Yii.CJSONDataSource.prototype._cacheKey = null;
-
- Yii.CJSONDataSource.prototype.cache = function (duration, dependency) {
- this.cacheDuration = duration;
- this.cacheDependency = dependency;
- };
- /**
- * Gets the cache key
- */
- Yii.CJSONDataSource.prototype.getCacheKey = function() {
- if (this._cacheKey === null) {
- this._cacheKey = Yii.CJSON.encode(this.ajaxOptions);
- }
- return this._cacheKey;
- };
- /**
- * Whether to use JSONP or not, defaults to false meaning use AJAX for requests.
- * @var Boolean
- */
- Yii.CJSONDataSource.prototype.useJSONP = false;
-
- /**
- * Options to pass to the ajax request.
- * @var Object
- */
- Yii.CJSONDataSource.prototype.ajaxOptions = {};
- /**
- * A list of actions and their respective URLs. has the format:
- * {
- * 'list': 'http://example.com/products/list.json',
- * 'search': ['product/search', {'format': 'json'}],
- * 'create': ['product/create', {'format': 'json'}],
- * 'update': ['product/update', {'format': 'json'}]
- * }
- * @see Yii.CHtml.normalizeUrl
- * @var Object
- */
- Yii.CJSONDataSource.prototype.routes = {};
- /**
- * Makes the request and executes the callback when data arrives.
- * @param {Function} callback The callback function to execute, this will recieve the
- * data as its first parameter and the data source as its second parameter.
- * @returns {jQuery.ajaxRequest} The ajax request
- */
- Yii.CJSONDataSource.prototype.makeRequest = function (callback) {
- var options, source = this, result;
- if (this.ajaxOptions.type === undefined) {
- this.ajaxOptions.type = "GET";
- }
- this.ajaxOptions.success = function (data) {
- if (source.cacheDuration !== null && source.ajaxOptions.type.toLowerCase() === "get") {
- Yii.app().getCache().set(source.getCacheKey(), data, source.cacheDuration);
- }
- callback(data, source);
- };
- if (source.ajaxOptions.type.toLowerCase() === "get" && source.cacheDuration !== null && (result = Yii.app().getCache().get(source.getCacheKey())) !== false) {
- return callback(result, source);
- }
-
- return Yii.app().ajax.makeRequest(this.ajaxOptions);
- };
-
- /**
- * Gets a list of items from the data source
- * @param {Function} callback the callback function to execute, this will
- * receive the response from the server as its first parameter and the data source
- * as the second parameter
- * @returns {jQuery.ajaxRequest} The ajax request
- */
- Yii.CJSONDataSource.prototype.list = function (callback) {
-
- this.ajaxOptions.url = this.routes.list;
- return this.makeRequest(callback);
- };
-
- /**
- * Searches for items from the data source.
- * @param {Object} criteria The search criteria, field:'search query'
- * @param {Function} callback the callback function to execute, this will
- * receive the response from the server as its first parameter and the data source
- * as the second parameter
- * @returns {jQuery.ajaxRequest} The ajax request
- */
- Yii.CJSONDataSource.prototype.search = function (criteria, callback) {
- this.ajaxOptions.data = criteria;
- this.ajaxOptions.url = this.routes.search;
- return this.makeRequest(callback);
- };
-
- /**
- * Creates a new item.
- * @param {Object} data The data to post to the server
- * @param {Function} callback the callback function to execute, this will
- * receive the response from the server as its first parameter and the data source
- * as the second parameter
- * @returns {jQuery.ajaxRequest} The ajax request
- */
- Yii.CJSONDataSource.prototype.create = function (data, callback) {
- this.ajaxOptions.data = data;
- if (this.ajaxOptions.type === undefined || this.ajaxOptions.type.toLowerCase() === "get") {
- this.ajaxOptions.type = "post";
- }
- this.ajaxOptions.url = this.routes.create;
- return this.makeRequest(callback);
- };
-
- /**
- * Updates an item
- * @param {Object} data The data to post to the server
- * @param {Function} callback the callback function to execute, this will
- * receive the response from the server as its first parameter and the data source
- * as the second parameter
- * @returns {jQuery.ajaxRequest} The ajax request
- */
- Yii.CJSONDataSource.prototype.update = function (data, callback) {
- this.ajaxOptions.data = data;
- if (this.ajaxOptions.type === undefined || this.ajaxOptions.type.toLowerCase() === "get") {
- this.ajaxOptions.type = "post";
- }
- this.ajaxOptions.url = this.routes.update;
- return this.makeRequest(callback);
- };
-
- /**
- * Deletes an item
- * @param {Object} data The data to post to the server
- * @param {Function} callback the callback function to execute, this will
- * receive the response from the server as its first parameter and the data source
- * as the second parameter
- * @returns {jQuery.ajaxRequest} The ajax request
- */
- Yii.CJSONDataSource.prototype.remove = function (data, callback) {
- this.ajaxOptions.data = data;
- if (this.ajaxOptions.type === undefined || this.ajaxOptions.type.toLowerCase() === "get") {
- this.ajaxOptions.type = "post";
- }
- this.ajaxOptions.url = this.routes.remove;
- return this.makeRequest(callback);
- };
-
- /*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CChoiceFormat is a helper that chooses an appropriate message based on the specified number value.
- * The candidate messages are given as a string in the following format:
- * <pre>
- * 'expr1#message1|expr2#message2|expr3#message3'
- * </pre>
- * where each expression should be a valid PHP expression with 'n' as the only variable.
- * For example, 'n==1' and 'n%10==2 && n>10' are both valid expressions.
- * The variable 'n' will take the given number value, and if an expression evaluates true,
- * the corresponding message will be returned.
- *
- * For example, given the candidate messages 'n==1#one|n==2#two|n>2#others' and
- * the number value 2, the resulting message will be 'two'.
- *
- * For expressions like 'n==1', we can also use a shortcut '1'. So the above example
- * candidate messages can be simplified as '1#one|2#two|n>2#others'.
- *
- * In case the given number doesn't select any message, the last candidate message
- * will be returned.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CChoiceFormat.php 2899 2011-01-20 21:10:03Z alexander.makarow $
- * @package system.i18n
- * @since 1.0.2
- * @author Charles Pick
- * @class
- */
- Yii.CChoiceFormat = function CChoiceFormat () {
- };
- /**
- * Formats a message according to the specified number value.
- * @param {String} messages the candidate messages in the format of 'expr1#message1|expr2#message2|expr3#message3'.
- * See {@link CChoiceFormat} for more details.
- * @param {Mixed} number the number value
- * @returns {String} the selected message
- */
- Yii.CChoiceFormat.prototype.format = function (messages, number) {
- var n, matches, i, expression, message, match;
- matches = (messages + "|").match(/\s*([^#]*)\s*#([^\|]*)\|/g);
- if (matches !== null) {
- n = matches.length;
- }
- else {
- return messages;
- }
- if(n===0) {
- return messages;
- }
- for(i=0;i<n;++i) {
- match = matches[i].match(/\s*([^#]*)\s*#([^\|]*)\|/);
- expression=match[0];
- message=match[1];
- if(expression===String(Number(expression))) {
- if(expression==number) {
- return message;
- }
- }
- else if(this.evaluate(expression,number)) {
- return message;
- }
- }
- return message; // return the last choice
- };
- /**
- * Evaluates a PHP expression with the given number value.
- * @param {String} expression the PHP expression
- * @param {Mixed} n the number value
- * @returns {Boolean} the expression result
- */
- Yii.CChoiceFormat.prototype.evaluate = function (expression, n) {
- return eval(expression);
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CDateFormatter provides date/time localization functionalities.
- *
- * CDateFormatter allows you to format dates and times in a locale-sensitive manner.
- * Patterns are interpreted in the locale that the CDateFormatter instance
- * is associated with. For example, month names and weekday names may vary
- * under different locales, which yields different formatting results.
- * The patterns that CDateFormatter recognizes are as defined in
- * {@link http://www.unicode.org/reports/tr35/#Date_Format_Patterns CLDR}.
- *
- * CDateFormatter supports predefined patterns as well as customized ones:
- * <ul>
- * <li>The method {@link formatDateTime()} formats date or time or both using
- * predefined patterns which include 'full', 'long', 'medium' (default) and 'short'.</li>
- * <li>The method {@link format()} formats datetime using the specified pattern.
- * See {@link http://www.unicode.org/reports/tr35/#Date_Format_Patterns} for
- * details about the recognized pattern characters.</li>
- * </ul>
- *
- * @originalAuthor Wei Zhuo <weizhuo[at]gmail[dot]com>
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CDateFormatter.php 2798 2011-01-01 19:29:03Z qiang.xue $
- * @package system.i18n
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CComponent
- */
- Yii.CDateFormatter = function CDateFormatter (locale) {
- if (locale !== false) {
- this.construct(false);
- }
- };
- Yii.CDateFormatter.prototype = new Yii.CComponent();
- Yii.CDateFormatter.prototype.constructor = Yii.CDateFormatter;
- /**
- * @var {Array} pattern characters mapping to the corresponding translator methods
- */
- Yii.CDateFormatter.prototype._formatters = {'G':'formatEra','y':'formatYear','M':'formatMonth','L':'formatMonth','d':'formatDay','h':'formatHour12','H':'formatHour24','m':'formatMinutes','s':'formatSeconds','E':'formatDayInWeek','c':'formatDayInWeek','e':'formatDayInWeek','D':'formatDayInYear','F':'formatDayInMonth','w':'formatWeekInYear','W':'formatWeekInMonth','a':'formatPeriod','k':'formatHourInDay','K':'formatHourInPeriod','z':'formatTimeZone','Z':'formatTimeZone','v':'formatTimeZone'};
- Yii.CDateFormatter.prototype._locale = null;
- Yii.CDateFormatter.prototype._formats = [];
- /**
- * Constructor.
- * @param {Mixed} locale locale ID (string) or CLocale instance
- */
- Yii.CDateFormatter.prototype.construct = function (locale) {
- if(typeof(locale) === 'string') {
- this._locale=Yii.CLocale.getInstance(locale);
- }
- else {
- this._locale=locale;
- }
- };
- /**
- * Formats a date according to a customized pattern.
- * @param {String} pattern the pattern (See {@link http://www.unicode.org/reports/tr35/#Date_Format_Patterns})
- * @param {Mixed} time UNIX timestamp or a string in strtotime format
- * @returns {String} formatted date time.
- */
- Yii.CDateFormatter.prototype.format = function (pattern, time) {
- var date, tokens, i, token;
- if(typeof(time) === 'string')
- {
- if(php.ctype_digit(time)) {
- time=Number(time);
- }
- else {
- time=php.strtotime(time);
- }
- }
- date=Yii.CTimestamp.getdate(time,false,false);
- tokens=this.parseFormat(pattern);
- for (i in tokens) {
- if (tokens.hasOwnProperty(i)) {
-
- if(Object.prototype.toString.call(tokens[i]) === '[object Array]') {
- // a callback: method name, sub-pattern
- tokens[i]=this[tokens[i][0]](tokens[i][1],date);
- }
- }
- }
- return tokens.join('');
- };
- /**
- * Formats a date according to a predefined pattern.
- * The predefined pattern is determined based on the date pattern width and time pattern width.
- * @param {Mixed} timestamp UNIX timestamp or a string in strtotime format
- * @param {String} dateWidth width of the date pattern. It can be 'full', 'long', 'medium' and 'short'.
- * If null, it means the date portion will NOT appear in the formatting result
- * @param {String} timeWidth width of the time pattern. It can be 'full', 'long', 'medium' and 'short'.
- * If null, it means the time portion will NOT appear in the formatting result
- * @returns {String} formatted date time.
- */
- Yii.CDateFormatter.prototype.formatDateTime = function (timestamp, dateWidth, timeWidth) {
- var date, time, dateTimePattern;
- if (dateWidth === undefined) {
- dateWidth = 'medium';
- }
- if (timeWidth === undefined) {
- timeWidth = 'medium';
- }
- if(!php.empty(dateWidth)) {
- date=this.format(this._locale.getDateFormat(dateWidth),timestamp);
- }
- if(!php.empty(timeWidth)) {
- time=this.format(this._locale.getTimeFormat(timeWidth),timestamp);
- }
- if(date !== undefined && time !== undefined) {
- dateTimePattern=this._locale.getDateTimeFormat();
- return php.strtr(dateTimePattern,{'{0}':time,'{1}':date});
- }
- else if(date !== undefined) {
- return date;
- }
- else if(time !== undefined) {
- return time;
- }
- };
- /**
- * Parses the datetime format pattern.
- * @param {String} pattern the pattern to be parsed
- * @returns {Array} tokenized parsing result
- */
- Yii.CDateFormatter.prototype.parseFormat = function (pattern) {
- var tokens, n, isLiteral, literal, i, c, j, p, _formatters;
-
- if(this._formats[pattern] !== undefined) {
- return this._formats[pattern];
- }
- tokens=[];
- n=php.strlen(pattern);
- isLiteral=false;
- literal='';
- for(i=0;i<n;++i) {
- c=pattern[i];
- if(c==="'") {
- if(i<n-1 && pattern[i+1]==="'"){
- tokens.push("'");
- i++;
- }
- else if(isLiteral){
- tokens.push(literal);
- literal='';
- isLiteral=false;
- }
- else{
- isLiteral=true;
- literal='';
- }
- }
- else if(isLiteral) {
- literal+=c;
- }
- else {
- for(j=i+1;j<n;++j) {
- if(pattern[j]!==c) {
- break;
- }
- }
- p=php.str_repeat(c,j-i);
- if(this._formatters[c] !== undefined) {
- tokens.push([this._formatters[c],p]);
- }
- else {
- tokens.push(p);
- }
- i=j-1;
- }
- }
- if(literal!=='') {
- tokens.push(literal);
- }
- return (this._formats[pattern]=tokens);
- };
- /**
- * Get the year.
- * "yy" will return the last two digits of year.
- * "y...y" will pad the year with 0 in the front, e.g. "yyyyy" will generate "02008" for year 2008.
- * @param {String} pattern a pattern.
- * @param {Array} date result of {@link CTimestamp::getdate}.
- * @returns {String} formatted year
- */
- Yii.CDateFormatter.prototype.formatYear = function (pattern, date) {
- var year;
- year=date.year;
- if(pattern==='yy') {
- return php.str_pad(year%100,2,'0','STR_PAD_LEFT');
- }
- else {
- return php.str_pad(year,php.strlen(pattern),'0','STR_PAD_LEFT');
- }
- };
- /**
- * Get the month.
- * "M" will return integer 1 through 12;
- * "MM" will return two digits month number with necessary zero padding, e.g. 05;
- * "MMM" will return the abrreviated month name, e.g. "Jan";
- * "MMMM" will return the full month name, e.g. "January";
- * "MMMMM" will return the narrow month name, e.g. "J";
- * @param {String} pattern a pattern.
- * @param {Array} date result of {@link CTimestamp::getdate}.
- * @returns {String} month name
- */
- Yii.CDateFormatter.prototype.formatMonth = function (pattern, date) {
- var month;
- month=date.mon;
- switch(pattern) {
- case 'M':
- return month;
- case 'MM':
- return php.str_pad(month,2,'0','STR_PAD_LEFT');
- case 'MMM':
- return this._locale.getMonthName(month,'abbreviated');
- case 'MMMM':
- return this._locale.getMonthName(month,'wide');
- case 'MMMMM':
- return this._locale.getMonthName(month,'narrow');
- case 'L':
- return month;
- case 'LL':
- return php.str_pad(month,2,'0','STR_PAD_LEFT');
- case 'LLL':
- return this._locale.getMonthName(month,'abbreviated', true);
- case 'LLLL':
- return this._locale.getMonthName(month,'wide', true);
- case 'LLLLL':
- return this._locale.getMonthName(month,'narrow', true);
- default:
- throw new Yii.CException(Yii.t('yii','The pattern for month must be "M", "MM", "MMM", "MMMM", "L", "LL", "LLL" or "LLLL".'));
- }
- };
- /**
- * Get the day of the month.
- * "d" for non-padding, "dd" will always return 2 digits day numbers, e.g. 05.
- * @param {String} pattern a pattern.
- * @param {Array} date result of {@link CTimestamp::getdate}.
- * @returns {String} day of the month
- */
- Yii.CDateFormatter.prototype.formatDay = function (pattern, date) {
- var day;
- day=date.mday;
- if(pattern==='d') {
- return day;
- }
- else if(pattern==='dd') {
- return php.str_pad(day,2,'0','STR_PAD_LEFT');
- }
- else {
- throw new Yii.CException(Yii.t('yii','The pattern for day of the month must be "d" or "dd".'));
- }
- };
- /**
- * Get the day in the year, e.g. [1-366]
- * @param {String} pattern a pattern.
- * @param {Array} date result of {@link CTimestamp::getdate}.
- * @returns {Integer} hours in AM/PM format.
- */
- Yii.CDateFormatter.prototype.formatDayInYear = function (pattern, date) {
- var day, n;
- day=date.yday;
- if((n=php.strlen(pattern))<=3) {
- return php.str_pad(day,n,'0','STR_PAD_LEFT');
- }
- else {
- throw new Yii.CException(Yii.t('yii','The pattern for day in year must be "D", "DD" or "DDD".'));
- }
- };
- /**
- * Get day of week in the month, e.g. 2nd Wed in July.
- * @param {String} pattern a pattern.
- * @param {Array} date result of {@link CTimestamp::getdate}.
- * @returns {Integer} day in month
- * @see http://www.unicode.org/reports/tr35/#Date_Format_Patterns
- */
- Yii.CDateFormatter.prototype.formatDayInMonth = function (pattern, date) {
- if(pattern==='F') {
- return Number((date.mday+6)/7);
- }
- else {
- throw new Yii.CException(Yii.t('yii','The pattern for day in month must be "F".'));
- }
- };
- /**
- * Get the day of the week.
- * "E", "EE", "EEE" will return abbreviated week day name, e.g. "Tues";
- * "EEEE" will return full week day name;
- * "EEEEE" will return the narrow week day name, e.g. "T";
- * @param {String} pattern a pattern.
- * @param {Array} date result of {@link CTimestamp::getdate}.
- * @returns {String} day of the week.
- * @see http://www.unicode.org/reports/tr35/#Date_Format_Patterns
- */
- Yii.CDateFormatter.prototype.formatDayInWeek = function (pattern, date) {
- var day;
- day=date.wday;
- switch(pattern) {
- case 'E':
- case 'EE':
- case 'EEE':
- case 'eee':
- return this._locale.getWeekDayName(day,'abbreviated');
- case 'EEEE':
- case 'eeee':
- return this._locale.getWeekDayName(day,'wide');
- case 'EEEEE':
- case 'eeeee':
- return this._locale.getWeekDayName(day,'narrow');
- case 'e':
- case 'ee':
- case 'c':
- return day ? day : 7;
- case 'ccc':
- return this._locale.getWeekDayName(day,'abbreviated',true);
- case 'cccc':
- return this._locale.getWeekDayName(day,'wide',true);
- case 'ccccc':
- return this._locale.getWeekDayName(day,'narrow',true);
- default:
- throw new Yii.CException(Yii.t('yii','The pattern for day of the week must be "E", "EE", "EEE", "EEEE", "EEEEE", "e", "ee", "eee", "eeee", "eeeee", "c", "cccc" or "ccccc".'));
- }
- };
- /**
- * Get the AM/PM designator, 12 noon is PM, 12 midnight is AM.
- * @param {String} pattern a pattern.
- * @param {Array} date result of {@link CTimestamp::getdate}.
- * @returns {String} AM or PM designator
- */
- Yii.CDateFormatter.prototype.formatPeriod = function (pattern, date) {
- if(pattern==='a') {
- if(php.intval(date.hours/12)) {
- return this._locale.getPMName();
- }
- else {
- return this._locale.getAMName();
- }
- }
- else {
- throw new Yii.CException(Yii.t('yii','The pattern for AM/PM marker must be "a".'));
- }
- };
- /**
- * Get the hours in 24 hour format, i.e. [0-23].
- * "H" for non-padding, "HH" will always return 2 characters.
- * @param {String} pattern a pattern.
- * @param {Array} date result of {@link CTimestamp::getdate}.
- * @returns {String} hours in 24 hour format.
- */
- Yii.CDateFormatter.prototype.formatHour24 = function (pattern, date) {
- var hour;
- hour=date.hours;
- if(pattern==='H') {
- return hour;
- }
- else if(pattern==='HH') {
- return php.str_pad(hour,2,'0','STR_PAD_LEFT');
- }
- else {
- throw new Yii.CException(Yii.t('yii','The pattern for 24 hour format must be "H" or "HH".'));
- }
- };
- /**
- * Get the hours in 12 hour format, i.e., [1-12]
- * "h" for non-padding, "hh" will always return 2 characters.
- * @param {String} pattern a pattern.
- * @param {Array} date result of {@link CTimestamp::getdate}.
- * @returns {String} hours in 12 hour format.
- */
- Yii.CDateFormatter.prototype.formatHour12 = function (pattern, date) {
- var hour;
- hour=date.hours;
- hour=(hour==12|hour===0)?12:(hour)%12;
- if(pattern==='h') {
- return hour;
- }
- else if(pattern==='hh') {
- return php.str_pad(hour,2,'0','STR_PAD_LEFT');
- }
- else {
- throw new Yii.CException(Yii.t('yii','The pattern for 12 hour format must be "h" or "hh".'));
- }
- };
- /**
- * Get the hours [1-24].
- * 'k' for non-padding, and 'kk' with 2 characters padding.
- * @param {String} pattern a pattern.
- * @param {Array} date result of {@link CTimestamp::getdate}.
- * @returns {Integer} hours [1-24]
- */
- Yii.CDateFormatter.prototype.formatHourInDay = function (pattern, date) {
- var hour;
- hour=date.hours==0?24:date.hours;
- if(pattern==='k') {
- return hour;
- }
- else if(pattern==='kk') {
- return php.str_pad(hour,2,'0','STR_PAD_LEFT');
- }
- else {
- throw new Yii.CException(Yii.t('yii','The pattern for hour in day must be "k" or "kk".'));
- }
- };
- /**
- * Get the hours in AM/PM format, e.g [0-11]
- * "K" for non-padding, "KK" will always return 2 characters.
- * @param {String} pattern a pattern.
- * @param {Array} date result of {@link CTimestamp::getdate}.
- * @returns {Integer} hours in AM/PM format.
- */
- Yii.CDateFormatter.prototype.formatHourInPeriod = function (pattern, date) {
- var hour;
- hour=date.hours%12;
- if(pattern==='K') {
- return hour;
- }
- else if(pattern==='KK') {
- return php.str_pad(hour,2,'0','STR_PAD_LEFT');
- }
- else {
- throw new Yii.CException(Yii.t('yii','The pattern for hour in AM/PM must be "K" or "KK".'));
- }
- };
- /**
- * Get the minutes.
- * "m" for non-padding, "mm" will always return 2 characters.
- * @param {String} pattern a pattern.
- * @param {Array} date result of {@link CTimestamp::getdate}.
- * @returns {String} minutes.
- */
- Yii.CDateFormatter.prototype.formatMinutes = function (pattern, date) {
- var minutes;
- minutes=date.minutes;
- if(pattern==='m') {
- return minutes;
- }
- else if(pattern==='mm') {
- return php.str_pad(minutes,2,'0','STR_PAD_LEFT');
- }
- else {
- throw new Yii.CException(Yii.t('yii','The pattern for minutes must be "m" or "mm".'));
- }
- };
- /**
- * Get the seconds.
- * "s" for non-padding, "ss" will always return 2 characters.
- * @param {String} pattern a pattern.
- * @param {Array} date result of {@link CTimestamp::getdate}.
- * @returns {String} seconds
- */
- Yii.CDateFormatter.prototype.formatSeconds = function (pattern, date) {
- var seconds;
- seconds=date.seconds;
- if(pattern==='s') {
- return seconds;
- }
- else if(pattern==='ss') {
- return php.str_pad(seconds,2,'0','STR_PAD_LEFT');
- }
- else {
- throw new Yii.CException(Yii.t('yii','The pattern for seconds must be "s" or "ss".'));
- }
- };
- /**
- * Get the week in the year.
- * @param {String} pattern a pattern.
- * @param {Array} date result of {@link CTimestamp::getdate}.
- * @returns {Integer} week in year
- */
- Yii.CDateFormatter.prototype.formatWeekInYear = function (pattern, date) {
- if(pattern==='w') {
- return php.date('W',php.mktime(0,0,0,date.mon,date.mday,date.year));
- }
- else {
- throw new Yii.CException(Yii.t('yii','The pattern for week in year must be "w".'));
- }
- };
- /**
- * Get week in the month.
- * @param {Array} pattern result of {@link CTimestamp::getdate}.
- * @param {String} date a pattern.
- * @returns {Integer} week in month
- */
- Yii.CDateFormatter.prototype.formatWeekInMonth = function (pattern, date) {
- if(pattern==='W') {
- return php.date('W',php.mktime(0,0,0,date.mon, date.mday,date.year))-php.date('W', php.mktime(0,0,0,date.mon,1,date.year))+1;
- }
- else {
- throw new Yii.CException(Yii.t('yii','The pattern for week in month must be "W".'));
- }
- };
- /**
- * Get the timezone of the server machine.
- * @param {String} pattern a pattern.
- * @param {Array} date result of {@link CTimestamp::getdate}.
- * @returns {String} time zone
- * @todo How to get the timezone for a different region?
- */
- Yii.CDateFormatter.prototype.formatTimeZone = function (pattern, date) {
- if(pattern[0]==='z' || pattern[0]==='v') {
- return php.date('T', php.mktime(date.hours, date.minutes, date.seconds, date.mon, date.mday, date.year));
- }
- else if(pattern[0]==='Z') {
- return php.date('O', php.mktime(date.hours, date.minutes, date.seconds, date.mon, date.mday, date.year));
- }
- else {
- throw new Yii.CException(Yii.t('yii','The pattern for time zone must be "z" or "v".'));
- }
- };
- /**
- * Get the era. i.e. in gregorian, year > 0 is AD, else BC.
- * @param {String} pattern a pattern.
- * @param {Array} date result of {@link CTimestamp::getdate}.
- * @returns {String} era
- * @todo How to support multiple Eras?, e.g. Japanese.
- */
- Yii.CDateFormatter.prototype.formatEra = function (pattern, date) {
- var era;
- era=date.year>0 ? 1 : 0;
- switch(pattern)
- {
- case 'G':
- case 'GG':
- case 'GGG':
- return this._locale.getEraName(era,'abbreviated');
- case 'GGGG':
- return this._locale.getEraName(era,'wide');
- case 'GGGGG':
- return this._locale.getEraName(era,'narrow');
- default:
- throw new Yii.CException(Yii.t('yii','The pattern for era must be "G", "GG", "GGG", "GGGG" or "GGGGG".'));
- }
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CJavaScriptMessageSource represents a message source that stores translated messages in JavaScript scripts.
- *
- * CJavaScriptMessageSource uses JavaScript files and arrays to keep message translations.
- * <ul>
- * <li>All translations are saved under the {@link basePath} directory.</li>
- * <li>Translations in one language are kept as JavaScript files under an individual subdirectory
- * whose name is the same as the language ID. Each JavaScript file contains messages
- * belonging to the same category, and the file name is the same as the category name.</li>
- * <li>Within a JavaScript file, an object of (source, translation) pairs is returned.
- * For example:
- * <pre>
- * ({
- * 'original message 1' : 'translated message 1',
- * 'original message 2' : 'translated message 2'
- * });
- * </pre>
- * </li>
- * </ul>
- * When {@link cachingDuration} is set as a positive number, message translations will be cached.
- *
- * Starting from version 1.0.10, messages for an extension class (e.g. a widget, a module) can be specially managed and used.
- * In particular, if a message belongs to an extension whose class name is Xyz, then the message category
- * can be specified in the format of 'Xyz.categoryName'. And the corresponding message file
- * is assumed to be 'BasePath/messages/LanguageID/categoryName.php', where 'BasePath' refers to
- * the directory that contains the extension class file. When using Yii.t() to translate an extension message,
- * the category name should be set as 'Xyz.categoryName'.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CJavaScriptMessageSource.php 2798 2011-01-01 19:29:03Z qiang.xue $
- * @package system.i18n
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CMessageSource
- */
- Yii.CJavaScriptMessageSource = function CJavaScriptMessageSource () {
- };
- Yii.CJavaScriptMessageSource.prototype = new Yii.CMessageSource(false);
- Yii.CJavaScriptMessageSource.prototype.constructor = Yii.CJavaScriptMessageSource;
- /**
- * @const
- */
- Yii.CJavaScriptMessageSource.CACHE_KEY_PREFIX = 'Yii.CJavaScriptMessageSource.';
- /**
- * @var {Integer} the time in seconds that the messages can remain valid in cache.
- * Defaults to 0, meaning the caching is disabled.
- */
- Yii.CJavaScriptMessageSource.prototype.cachingDuration = 0;
- /**
- * @var {String} the ID of the cache application component that is used to cache the messages.
- * Defaults to 'cache' which refers to the primary cache application component.
- * Set this property to false if you want to disable caching the messages.
- * @since 1.0.10
- */
- Yii.CJavaScriptMessageSource.prototype.cacheID = 'cache';
- /**
- * @var {String} the base path for all translated messages. Defaults to null, meaning
- * the "messages" subdirectory of the application directory (e.g. "protected/messages").
- */
- Yii.CJavaScriptMessageSource.prototype.basePath = null;
- Yii.CJavaScriptMessageSource.prototype._files = {};
- /**
- * Initializes the application component.
- * This method overrides the parent implementation by preprocessing
- * the user request data.
- */
- Yii.CJavaScriptMessageSource.prototype.init = function () {
- Yii.CMessageSource.prototype.init.call(this);
- if(this.basePath===null) {
- this.basePath=Yii.getPathOfAlias('application.messages');
- }
- };
- /**
- * Determines the message file name based on the given category and language.
- * If the category name contains a dot, it will be split into the module class name and the category name.
- * In this case, the message file will be assumed to be located within the 'messages' subdirectory of
- * the directory containing the module class file.
- * Otherwise, the message file is assumed to be under the {@link basePath}.
- * @param {String} category category name
- * @param {String} language language ID
- * @returns {String} the message file path
- * @since 1.0.10
- */
- Yii.CJavaScriptMessageSource.prototype.getMessageFile = function (category, language) {
- var pos, moduleClass, moduleCategory, classVar;
- if (this._files[category] === undefined) {
- this._files[category] = {};
- }
- if(this._files[category][language] === undefined) {
-
- if((pos=php.strpos(category,'.'))!==false) {
- moduleClass=category.slice(0, pos);
- moduleCategory=category.slice(pos+1);
- this._files[category][language]=Yii.getPathOfAlias(moduleClass + ".messages." + moduleCategory) + ".js";
- }
- else {
- this._files[category][language]=this.basePath+'/'+language+'/'+category+'.js';
- }
- }
- return this._files[category][language];
- };
- /**
- * Loads the message translation for the specified language and category.
- * @param {String} category the message category
- * @param {String} language the target language
- * @returns {Object} the loaded messages
- */
- Yii.CJavaScriptMessageSource.prototype.loadMessages = function (category, language) {
- var messageFile, cache, key, data, messages, dependency;
- messageFile=this.getMessageFile(category,language);
- if(this.cachingDuration>0 && this.cacheID!==false && (cache=Yii.app().getComponent(this.cacheID))!==null) {
- key=this.Yii.CACHE_KEY_PREFIX + messageFile;
- if((data=cache.get(key))!==false) {
- if (!data instanceof "Object") {
- data = Yii.CJSON.decode(data);
- }
- return data;
- }
- }
- try {
- data = Yii.include(messageFile, false);
- if (data === false) {
- return {};
- }
- if (this.cachingDuration > 0 && this.cacheID !== false && (cache=Yii.app().getComponent(this.cacheID))!==null) {
- key=this.Yii.CACHE_KEY_PREFIX + messageFile;
- cache.set(key, data, this.cachingDuration);
- }
- return data;
- }
- catch (e) {
- return {};
- }
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CLocale represents the data relevant to a locale.
- *
- * The data includes the number formatting information and date formatting information.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CLocale.php 2844 2011-01-13 01:29:55Z alexander.makarow $
- * @package system.i18n
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CComponent
- */
- Yii.CLocale = function CLocale (id) {
-
- if (id !== false) {
- this.construct(id);
- }
- };
- Yii.CLocale._locales = null;
- Yii.CLocale.prototype = new Yii.CComponent();
- Yii.CLocale.prototype.constructor = Yii.CLocale;
- /**
- * @var {String} the directory that contains the locale data. If this property is not set,
- * the locale data will be loaded from 'framework/i18n/data'.
- * @since 1.1.0
- */
- Yii.CLocale.prototype.dataPath = null;
- Yii.CLocale.prototype._id = null;
- Yii.CLocale.prototype._data = null;
- Yii.CLocale.prototype._dateFormatter = null;
- Yii.CLocale.prototype._numberFormatter = null;
- /**
- * Returns the instance of the specified locale.
- * Since the constructor of CLocale is protected, you can only use
- * this method to obtain an instance of the specified locale.
- * @param {String} id the locale ID (e.g. en_US)
- * @returns {Yii.CLocale} the locale instance
- */
- Yii.CLocale.getInstance = function (id) {
-
- if(this._locales === null) {
- this._locales = {};
- }
- if(this._locales[id] !== undefined) {
- return this._locales[id];
- }
- else {
- return (this._locales[id]=new Yii.CLocale(id));
- }
- };
- /**
- * @returns {Array} IDs of the locales which the framework can recognize
- */
- Yii.CLocale.prototype.getLocaleIDs = function () {
- var locales;
- locales=["aa","aa_dj","aa_er","aa_et","af","af_na","af_za","ak","ak_gh","am","am_et","ar","ar_ae","ar_bh","ar_dz","ar_eg","ar_iq","ar_jo","ar_kw","ar_lb","ar_ly","ar_ma","ar_om","ar_qa","ar_sa","ar_sd","ar_sy","ar_tn","ar_ye","as","as_in","asa","asa_tz","az","az_arab","az_arab_ir","az_az","az_cyrl","az_cyrl_az","az_ir","az_latn","az_latn_az","be","be_by","bem","bem_zm","bez","bez_tz","bg","bg_bg","bm","bm_ml","bn","bn_bd","bn_in","bo","bo_cn","bo_in","br","br_fr","brx","brx_in","bs","bs_ba","byn","byn_er","ca","ca_es","cch","cch_ng","cgg","cgg_ug","chr","chr_us","cs","cs_cz","cy","cy_gb","da","da_dk","dav","dav_ke","de","de_at","de_be","de_ch","de_de","de_li","de_lu","dv","dv_mv","dz","dz_bt","ebu","ebu_ke","ee","ee_gh","ee_tg","el","el_cy","el_gr","el_polyton","en","en_as","en_au","en_be","en_bw","en_bz","en_ca","en_dsrt","en_dsrt_us","en_gb","en_gu","en_hk","en_ie","en_in","en_jm","en_mh","en_mp","en_mt","en_mu","en_na","en_nz","en_ph","en_pk","en_sg","en_shaw","en_tt","en_um","en_us","en_us_posix","en_vi","en_za","en_zw","en_zz","eo","es","es_419","es_ar","es_bo","es_cl","es_co","es_cr","es_do","es_ec","es_es","es_gq","es_gt","es_hn","es_mx","es_ni","es_pa","es_pe","es_pr","es_py","es_sv","es_us","es_uy","es_ve","et","et_ee","eu","eu_es","fa","fa_af","fa_ir","ff","ff_sn","fi","fi_fi","fil","fil_ph","fo","fo_fo","fr","fr_be","fr_bf","fr_bi","fr_bj","fr_bl","fr_ca","fr_cd","fr_cf","fr_cg","fr_ch","fr_ci","fr_cm","fr_dj","fr_fr","fr_ga","fr_gn","fr_gp","fr_gq","fr_km","fr_lu","fr_mc","fr_mf","fr_mg","fr_ml","fr_mq","fr_ne","fr_re","fr_rw","fr_sn","fr_td","fr_tg","fur","fur_it","ga","ga_ie","gaa","gaa_gh","gez","gez_er","gez_et","gl","gl_es","gsw","gsw_ch","gu","gu_in","guz","guz_ke","gv","gv_gb","ha","ha_arab","ha_arab_ng","ha_arab_sd","ha_gh","ha_latn","ha_latn_gh","ha_latn_ne","ha_latn_ng","ha_ne","ha_ng","ha_sd","haw","haw_us","he","he_il","hi","hi_in","hr","hr_hr","hu","hu_hu","hy","hy_am","ia","id","id_id","ig","ig_ng","ii","ii_cn","in","is","is_is","it","it_ch","it_it","iu","iw","ja","ja_jp","jmc","jmc_tz","ka","ka_ge","kab","kab_dz","kaj","kaj_ng","kam","kam_ke","kcg","kcg_ng","kde","kde_tz","kea","kea_cv","kfo","kfo_ci","khq","khq_ml","ki","ki_ke","kk","kk_cyrl","kk_cyrl_kz","kk_kz","kl","kl_gl","kln","kln_ke","km","km_kh","kn","kn_in","ko","ko_kr","kok","kok_in","kpe","kpe_gn","kpe_lr","ksb","ksb_tz","ksh","ksh_de","ku","ku_arab","ku_arab_iq","ku_arab_ir","ku_iq","ku_ir","ku_latn","ku_latn_sy","ku_latn_tr","ku_sy","ku_tr","kw","kw_gb","ky","ky_kg","lag","lag_tz","lg","lg_ug","ln","ln_cd","ln_cg","lo","lo_la","lt","lt_lt","luo","luo_ke","luy","luy_ke","lv","lv_lv","mas","mas_ke","mas_tz","mer","mer_ke","mfe","mfe_mu","mg","mg_mg","mi","mi_nz","mk","mk_mk","ml","ml_in","mn","mn_cn","mn_cyrl","mn_cyrl_mn","mn_mn","mn_mong","mn_mong_cn","mo","mr","mr_in","ms","ms_bn","ms_my","mt","mt_mt","my","my_mm","naq","naq_na","nb","nb_no","nd","nd_zw","nds","nds_de","ne","ne_in","ne_np","nl","nl_be","nl_nl","nn","nn_no","no","nr","nr_za","nso","nso_za","ny","ny_mw","nyn","nyn_ug","oc","oc_fr","om","om_et","om_ke","or","or_in","pa","pa_arab","pa_arab_pk","pa_guru","pa_guru_in","pa_in","pa_pk","pl","pl_pl","ps","ps_af","pt","pt_ao","pt_br","pt_gw","pt_mz","pt_pt","rm","rm_ch","ro","ro_md","ro_ro","rof","rof_tz","root","ru","ru_md","ru_ru","ru_ua","rw","rw_rw","rwk","rwk_tz","sa","sa_in","saq","saq_ke","se","se_fi","se_no","seh","seh_mz","ses","ses_ml","sg","sg_cf","sh","sh_ba","sh_cs","sh_yu","shi","shi_latn","shi_latn_ma","shi_ma","shi_tfng","shi_tfng_ma","si","si_lk","sid","sid_et","sk","sk_sk","sl","sl_si","sn","sn_zw","so","so_dj","so_et","so_ke","so_so","sq","sq_al","sr","sr_ba","sr_cs","sr_cyrl","sr_cyrl_ba","sr_cyrl_cs","sr_cyrl_me","sr_cyrl_rs","sr_cyrl_yu","sr_latn","sr_latn_ba","sr_latn_cs","sr_latn_me","sr_latn_rs","sr_latn_yu","sr_me","sr_rs","sr_yu","ss","ss_sz","ss_za","ssy","ssy_er","st","st_ls","st_za","sv","sv_fi","sv_se","sw","sw_ke","sw_tz","syr","syr_sy","ta","ta_in","ta_lk","te","te_in","teo","teo_ke","teo_ug","tg","tg_cyrl","tg_cyrl_tj","tg_tj","th","th_th","ti","ti_er","ti_et","tig","tig_er","tl","tl_ph","tn","tn_za","to","to_to","tr","tr_tr","trv","trv_tw","ts","ts_za","tt","tt_ru","tzm","tzm_latn","tzm_latn_ma","tzm_ma","ug","ug_arab","ug_arab_cn","ug_cn","uk","uk_ua","ur","ur_in","ur_pk","uz","uz_af","uz_arab","uz_arab_af","uz_cyrl","uz_cyrl_uz","uz_latn","uz_latn_uz","uz_uz","ve","ve_za","vi","vi_vn","vun","vun_tz","wal","wal_et","wo","wo_latn","wo_latn_sn","wo_sn","xh","xh_za","xog","xog_ug","yo","yo_ng","zh","zh_cn","zh_hans","zh_hans_cn","zh_hans_hk","zh_hans_mo","zh_hans_sg","zh_hant","zh_hant_hk","zh_hant_mo","zh_hant_tw","zh_hk","zh_mo","zh_sg","zh_tw","zu","zu_za"];
-
- return locales;
- };
- /**
- * Constructor.
- * Since the constructor is protected, please use {@link getInstance}
- * to obtain an instance of the specified locale.
- * @param {String} id the locale ID (e.g. en_US)
- */
- Yii.CLocale.prototype.construct = function (id) {
- var dataPath, dataFile;
- this._id=this.getCanonicalID(id);
- dataPath=this.dataPath===null ? YII_PATH + '/i18n/data' : this.dataPath;
- dataFile=dataPath+"/"+this._id+'.js';
- this._data= Yii.include(dataFile,false);
-
- };
- /**
- * Converts a locale ID to its canonical form.
- * In canonical form, a locale ID consists of only underscores and lower-case letters.
- * @param {String} id the locale ID to be converted
- * @returns {String} the locale ID in canonical form
- */
- Yii.CLocale.prototype.getCanonicalID = function (id) {
- return php.str_replace('-','_',id).toLowerCase();
- };
- /**
- * @returns {String} the locale ID (in canonical form)
- */
- Yii.CLocale.prototype.getId = function () {
- return this._id;
- };
- /**
- * @returns {Yii.CNumberFormatter} the number formatter for this locale
- */
- Yii.CLocale.prototype.getNumberFormatter = function () {
- if(this._numberFormatter===null) {
- this._numberFormatter=new Yii.CNumberFormatter(this);
- }
- return this._numberFormatter;
- };
- /**
- * @returns {Yii.CDateFormatter} the date formatter for this locale
- */
- Yii.CLocale.prototype.getDateFormatter = function () {
- if(this._dateFormatter===null) {
- this._dateFormatter=new Yii.CDateFormatter(this);
- }
- return this._dateFormatter;
- };
- /**
- * @param {String} currency 3-letter ISO 4217 code. For example, the code "USD" represents the US Dollar and "EUR" represents the Euro currency.
- * @returns {String} the localized currency symbol. Null if the symbol does not exist.
- */
- Yii.CLocale.prototype.getCurrencySymbol = function (currency) {
- return this._data.currencySymbols[currency] !== undefined ? this._data.currencySymbols[currency] : null;
- };
- /**
- * @param {String} name symbol name
- * @returns {String} symbol
- */
- Yii.CLocale.prototype.getNumberSymbol = function (name) {
- return this._data.numberSymbols[name] !== undefined ? this._data.numberSymbols[name] : null;
- };
- /**
- * @returns {String} the decimal format
- */
- Yii.CLocale.prototype.getDecimalFormat = function () {
- return this._data.decimalFormat;
- };
- /**
- * @returns {String} the currency format
- */
- Yii.CLocale.prototype.getCurrencyFormat = function () {
- return this._data.currencyFormat;
- };
- /**
- * @returns {String} the percent format
- */
- Yii.CLocale.prototype.getPercentFormat = function () {
- return this._data.percentFormat;
- };
- /**
- * @returns {String} the scientific format
- */
- Yii.CLocale.prototype.getScientificFormat = function () {
- return this._data.scientificFormat;
- };
- /**
- * @param {Integer} month month (1-12)
- * @param {String} width month name width. It can be 'wide', 'abbreviated' or 'narrow'.
- * @param {Boolean} standAlone whether the month name should be returned in stand-alone format
- * @returns {String} the month name
- */
- Yii.CLocale.prototype.getMonthName = function (month, width, standAlone) {
- if (width === undefined) {
- width = 'wide';
- }
- if (standAlone === undefined) {
- standAlone = false;
- }
- if(standAlone) {
- return this._data.monthNamesSA[width][month] !== undefined ? this._data.monthNamesSA[width][month] : this._data.monthNames[width][month];
- }
- else {
- return this._data.monthNames[width][month] !== undefined ? this._data.monthNames[width][month] : this._data.monthNamesSA[width][month];
- }
- };
- /**
- * Returns the month names in the specified width.
- * @param {String} width month name width. It can be 'wide', 'abbreviated' or 'narrow'.
- * @param {Boolean} standAlone whether the month names should be returned in stand-alone format
- * @returns {Array} month names indexed by month values (1-12)
- * @since 1.0.9
- */
- Yii.CLocale.prototype.getMonthNames = function (width, standAlone) {
- if (width === undefined) {
- width = 'wide';
- }
- if (standAlone === undefined) {
- standAlone = false;
- }
- if(standAlone) {
- return this._data.monthNamesSA[width] !== undefined ? this._data.monthNamesSA[width] : this._data.monthNames[width];
- }
- else {
- return this._data.monthNames[width] !== undefined ? this._data.monthNames[width] : this._data.monthNamesSA[width];
- }
- };
- /**
- * @param {Integer} day weekday (0-6, 0 means Sunday)
- * @param {String} width weekday name width. It can be 'wide', 'abbreviated' or 'narrow'.
- * @param {Boolean} standAlone whether the week day name should be returned in stand-alone format
- * @returns {String} the weekday name
- */
- Yii.CLocale.prototype.getWeekDayName = function (day, width, standAlone) {
- if (width === undefined) {
- width = 'wide';
- }
- if (standAlone === undefined) {
- standAlone = false;
- }
- if(standAlone) {
- return this._data.weekDayNamesSA[width][day] !== undefined ? this._data.weekDayNamesSA[width][day] : this._data.weekDayNames[width][day];
- }
- else {
- return this._data.weekDayNames[width][day] !== undefined ? this._data.weekDayNames[width][day] : this._data.weekDayNamesSA[width][day];
- }
- };
- /**
- * Returns the week day names in the specified width.
- * @param {String} width weekday name width. It can be 'wide', 'abbreviated' or 'narrow'.
- * @param {Boolean} standAlone whether the week day name should be returned in stand-alone format
- * @returns {Array} the weekday names indexed by weekday values (0-6, 0 means Sunday, 1 Monday, etc.)
- * @since 1.0.9
- */
- Yii.CLocale.prototype.getWeekDayNames = function (width, standAlone) {
- if (width === undefined) {
- width = 'wide';
- }
- if (standAlone === undefined) {
- standAlone = false;
- }
- if(standAlone) {
- return this._data.weekDayNamesSA[width] !== undefined ? this._data.weekDayNamesSA[width] : this._data.weekDayNames[width];
- }
- else {
- return this._data.weekDayNames[width] !== undefined ? this._data.weekDayNames[width] : this._data.weekDayNamesSA[width];
- }
- };
- /**
- * @param {Integer} era era (0,1)
- * @param {String} width era name width. It can be 'wide', 'abbreviated' or 'narrow'.
- * @returns {String} the era name
- */
- Yii.CLocale.prototype.getEraName = function (era, width) {
- if (width === undefined) {
- width = 'wide';
- }
- return this._data.eraNames[width][era];
- };
- /**
- * @returns {String} the AM name
- */
- Yii.CLocale.prototype.getAMName = function () {
- return this._data.amName;
- };
- /**
- * @returns {String} the PM name
- */
- Yii.CLocale.prototype.getPMName = function () {
- return this._data.pmName;
- };
- /**
- * @param {String} width date format width. It can be 'full', 'long', 'medium' or 'short'.
- * @returns {String} date format
- */
- Yii.CLocale.prototype.getDateFormat = function (width) {
- if (width === undefined) {
- width = 'medium';
- }
- return this._data.dateFormats[width];
- };
- /**
- * @param {String} width time format width. It can be 'full', 'long', 'medium' or 'short'.
- * @returns {String} date format
- */
- Yii.CLocale.prototype.getTimeFormat = function (width) {
- if (width === undefined) {
- width = 'medium';
- }
- return this._data.timeFormats[width];
- };
- /**
- * @returns {String} datetime format, i.e., the order of date and time.
- */
- Yii.CLocale.prototype.getDateTimeFormat = function () {
- return this._data.dateTimeFormat;
- };
- /**
- * @returns {String} the character orientation, which is either 'ltr' (left-to-right) or 'rtl' (right-to-left)
- * @since 1.1.2
- */
- Yii.CLocale.prototype.getOrientation = function () {
- return this._data.orientation !== undefined ? this._data.orientation : 'ltr';
- };
- /**
- * @returns {Array} plural forms expressions
- */
- Yii.CLocale.prototype.getPluralRules = function () {
- return this._data.pluralRules !== undefined ? this._data.pluralRules : [];
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CMissingTranslationEvent represents the parameter for the {@link CMessageSource::onMissingTranslation onMissingTranslation} event.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CMessageSource.php 2798 2011-01-01 19:29:03Z qiang.xue $
- * @package system.i18n
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CEvent
- */
- Yii.CMissingTranslationEvent = function CMissingTranslationEvent (sender, params) {
- if (sender !== false) {
- this.construct(sender, params);
- }
- };
- Yii.CMissingTranslationEvent.prototype = new Yii.CEvent(false);
- Yii.CMissingTranslationEvent.prototype.constructor = Yii.CMissingTranslationEvent;
- /**
- * @var {String} the message to be translated
- */
- Yii.CMissingTranslationEvent.prototype.message = null;
- /**
- * @var {String} the category that the message belongs to
- */
- Yii.CMissingTranslationEvent.prototype.category = null;
- /**
- * @var {String} the ID of the language that the message is to be translated to
- */
- Yii.CMissingTranslationEvent.prototype.language = null;
- /**
- * Constructor.
- * @param {Mixed} sender sender of this event
- * @param {String} category the category that the message belongs to
- * @param {String} message the message to be translated
- * @param {String} language the ID of the language that the message is to be translated to
- */
- Yii.CMissingTranslationEvent.prototype.construct = function (sender, category, message, language) {
- Yii.CEvent.prototype.construct.call(this, sender);
- this.message=message;
- this.category=category;
- this.language=language;
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CLogFilter preprocesses the logged messages before they are handled by a log route.
- *
- * CLogFilter is meant to be used by a log route to preprocess the logged messages
- * before they are handled by the route. The default implementation of CLogFilter
- * prepends additional context information to the logged messages. In particular,
- * by setting {@link logVars}, predefined PHP variables such as
- * $_SERVER, $_POST, etc. can be saved as a log message, which may help identify/debug
- * issues encountered.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CLogFilter.php 2799 2011-01-01 19:31:13Z qiang.xue $
- * @package system.logging
- * @since 1.0.6
- * @author Charles Pick
- * @class
- * @extends Yii.CComponent
- */
- Yii.CLogFilter = function CLogFilter () {
- };
- Yii.CLogFilter.prototype = new Yii.CComponent();
- Yii.CLogFilter.prototype.constructor = Yii.CLogFilter;
- /**
- * @var {Boolean} whether to prefix each log message with the current user session ID.
- * Defaults to false.
- */
- Yii.CLogFilter.prototype.prefixSession = false;
- /**
- * @var {Boolean} whether to prefix each log message with the current user
- * {@link CWebUser::name name} and {@link CWebUser::id ID}. Defaults to false.
- */
- Yii.CLogFilter.prototype.prefixUser = false;
- /**
- * @var {Boolean} whether to log the current user name and ID. Defaults to true.
- */
- Yii.CLogFilter.prototype.logUser = true;
- /**
- * @var {Array} list of the predefined variables that should be logged.
- * Note that a variable must be globally accessible. Otherwise it won't be logged.
- */
- Yii.CLogFilter.prototype.logVars = [];
- /**
- * Filters the given log messages.
- * This is the main method of CLogFilter. It processes the log messages
- * by adding context information, etc.
- * @param {Array} logs the log messages
- */
- Yii.CLogFilter.prototype.filter = function (logs) {
- var message;
- if (!php.empty(logs)) {
- if((message=this.getContext())!=='') {
- php.array_unshift(logs,[message,Yii.CLogger.LEVEL_INFO,'application',YII_BEGIN_TIME]);
- }
- this.format(logs);
- }
- return logs;
- };
- /**
- * Formats the log messages.
- * The default implementation will prefix each message with session ID
- * if {@link prefixSession} is set true. It may also prefix each message
- * with the current user's name and ID if {@link prefixUser} is true.
- * @param {Array} logs the log messages
- */
- Yii.CLogFilter.prototype.format = function (logs) {
- var prefix, id, user, i, log;
- prefix='';
- if(this.prefixSession && (id=document.cookie.match(/PHPSESSID=[^;]+/))!==null) {
- prefix+="[" + id + "]";
- }
- if(this.prefixUser && (user=Yii.app().getComponent('user',false))!==null) {
- prefix+='['+user.getName()+']['+user.getId()+']';
- }
- if(prefix!=='') {
- for (i in logs) {
- if (logs.hasOwnProperty(i)) {
- logs[i][0]=prefix+' '+logs[i][0];
- }
- }
- }
- };
- /**
- * Generates the context information to be logged.
- * The default implementation will dump user information, system variables, etc.
- * @returns {String} the context information. If an empty string, it means no context information.
- */
- Yii.CLogFilter.prototype.getContext = function () {
- var context, user, i, name;
- context=[];
- if(this.logUser && (user=Yii.app().getComponent('user',false))!==null) {
- context.push('User: '+user.getName()+' (ID: '+user.getId()+')');
- }
- for (i in this.logVars) {
- if (this.logVars.hasOwnProperty(i)) {
- name = this.logVars[i];
- if(window[name] !== undefined) {
- context.push(name + " = " + window[name]);
- }
- }
- }
- return context.join("\n\n");
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CLogRouter manages log routes that record log messages in different media.
- *
- * For example, a file log route {@link CFileLogRoute} records log messages
- * in log files. An email log route {@link CEmailLogRoute} sends log messages
- * to specific email addresses. See {@link CLogRoute} for more details about
- * different log routes.
- *
- * Log routes may be configured in application configuration like following:
- * <pre>
- * {
- * 'preload':{'log'}, // preload log component when app starts
- * 'components':{
- * 'log':{
- * 'class':'CLogRouter',
- * 'routes':{
- * {
- * 'class':'CFileLogRoute',
- * 'levels':'trace, info',
- * 'categories':'system.*',
- * },
- * {
- * 'class':'CEmailLogRoute',
- * 'levels':'error, warning',
- * 'email':'admin@example.com',
- * },
- * ),
- * ),
- * ),
- * }
- * </pre>
- *
- * You can specify multiple routes with different filtering conditions and different
- * targets, even if the routes are of the same type.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CLogRouter.php 3066 2011-03-13 14:22:55Z qiang.xue $
- * @package system.logging
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CApplicationComponent
- */
- Yii.CLogRouter = function CLogRouter () {
- };
- Yii.CLogRouter.prototype = new Yii.CApplicationComponent();
- Yii.CLogRouter.prototype.constructor = Yii.CLogRouter;
- Yii.CLogRouter.prototype._routes = [];
- /**
- * Initializes this application component.
- * This method is required by the IApplicationComponent interface.
- */
- Yii.CLogRouter.prototype.init = function () {
- var route, name;
- Yii.CApplicationComponent.prototype.init();
- for (name in this._routes) {
- if (this._routes.hasOwnProperty(name)) {
- route = this._routes[name];
- route=Yii.createComponent(route);
- route.init();
- this._routes[name]=route;
- }
- }
- Yii.getLogger().attachEventHandler('onFlush',[this,'collectLogs']);
- Yii.app().attachEventHandler('onEndRequest',[this,'processLogs']);
-
- };
- /**
- * @returns {Array} the currently initialized routes
- */
- Yii.CLogRouter.prototype.getRoutes = function () {
- return new Yii.CMap(this._routes);
- };
- /**
- * @param {Array} config list of route configurations. Each array element represents
- * the configuration for a single route and has the following array structure:
- * <ul>
- * <li>class: specifies the class name or alias for the route class.</li>
- * <li>name-value pairs: configure the initial property values of the route.</li>
- * </ul>
- */
- Yii.CLogRouter.prototype.setRoutes = function (config) {
- var name, route;
- for (name in config) {
- if (config.hasOwnProperty(name)) {
- route = config[name];
- this._routes[name]=route;
- }
- }
-
- };
- /**
- * Collects log messages from a logger.
- * This method is an event handler to the {@link CLogger::onFlush} event.
- * @param {Yii.CEvent} event event parameter
- */
- Yii.CLogRouter.prototype.collectLogs = function (event) {
- var logger, dumpLogs, i, route;
- logger=Yii.getLogger();
- dumpLogs=event.params.dumpLogs !== undefined && event.params.dumpLogs;
- for (i in this._routes) {
- if (this._routes.hasOwnProperty(i)) {
- route = this._routes[i];
- if(route.enabled) {
- route.collectLogs(logger,dumpLogs);
- }
- }
- }
- };
- /**
- * Collects and processes log messages from a logger.
- * This method is an event handler to the {@link CApplication::onEndRequest} event.
- * @param {Yii.CEvent} event event parameter
- * @since 1.1.0
- */
- Yii.CLogRouter.prototype.processLogs = function (event) {
- var logger, i, route;
- logger=Yii.getLogger();
-
- for (i in this._routes) {
- if (this._routes.hasOwnProperty(i)) {
- route = this._routes[i];
-
- if(route.enabled) {
-
- route.collectLogs(logger,true);
-
- }
- }
- }
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CLogger records log messages in memory.
- *
- * CLogger implements the methods to retrieve the messages with
- * various filter conditions, including log levels and log categories.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CLogger.php 3137 2011-03-28 11:08:06Z mdomba $
- * @package system.logging
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CComponent
- */
- Yii.CLogger = function() {
- };
- Yii.CLogger.prototype = new Yii.CComponent();
- Yii.CLogger.prototype.constructor = Yii.CLogger;
- /**
- * @const
- */
- Yii.CLogger.prototype.LEVEL_TRACE = 'trace';
- /**
- * @const
- */
- Yii.CLogger.prototype.LEVEL_WARNING = 'warning';
- /**
- * @const
- */
- Yii.CLogger.prototype.LEVEL_ERROR = 'error';
- /**
- * @const
- */
- Yii.CLogger.prototype.LEVEL_INFO = 'info';
- /**
- * @const
- */
- Yii.CLogger.prototype.LEVEL_PROFILE = 'profile';
- /**
- * @var {Integer} how many messages should be logged before they are flushed to destinations.
- * Defaults to 10,000, meaning for every 10,000 messages, the {@link flush} method will be
- * automatically invoked once. If this is 0, it means messages will never be flushed automatically.
- * @since 1.1.0
- */
- Yii.CLogger.prototype.autoFlush = 10000;
- /**
- * @var {Array} log messages
- */
- Yii.CLogger.prototype._logs = [];
- /**
- * @var {Integer} number of log messages
- */
- Yii.CLogger.prototype._logCount = 0;
- /**
- * @var {Array} log levels for filtering (used when filtering)
- */
- Yii.CLogger.prototype._levels = null;
- /**
- * @var {Array} log categories for filtering (used when filtering)
- */
- Yii.CLogger.prototype._categories = null;
- /**
- * @var {Array} the profiling results (category, token => time in seconds)
- * @since 1.0.6
- */
- Yii.CLogger.prototype._timings = null;
- /**
- * Logs a message.
- * Messages logged by this method may be retrieved back via {@link getLogs}.
- * @param {String} message message to be logged
- * @param {String} level level of the message (e.g. 'Trace', 'Warning', 'Error'). It is case-insensitive.
- * @param {String} category category of the message (e.g. 'system.web'). It is case-insensitive.
- * @see getLogs
- */
- Yii.CLogger.prototype.log = function (message, level, category) {
- if (level === undefined) {
- level = 'info';
- }
- if (category === undefined) {
- category = 'application';
- }
- this._logs.push([message,level,category,php.microtime(true)]);
- this._logCount++;
- if(this.autoFlush>0 && this._logCount>=this.autoFlush) {
- this.flush();
- }
- };
- /**
- * Retrieves log messages.
- *
- * Messages may be filtered by log levels and/or categories.
- * A level filter is specified by a list of levels separated by comma or space
- * (e.g. 'trace, error'). A category filter is similar to level filter
- * (e.g. 'system, system.web'). A difference is that in category filter
- * you can use pattern like 'system.*' to indicate all categories starting
- * with 'system'.
- *
- * If you do not specify level filter, it will bring back logs at all levels.
- * The same applies to category filter.
- *
- * Level filter and category filter are combinational, i.e., only messages
- * satisfying both filter conditions will be returned.
- *
- * @param {String} levels level filter
- * @param {String} categories category filter
- * @returns {Array} list of messages. Each array elements represents one message
- * with the following structure:
- * array(
- * [0] => message (string)
- * [1] => level (string)
- * [2] => category (string)
- * [3] => timestamp (float, obtained by microtime(true));
- */
- Yii.CLogger.prototype.getLogs = function (levels, categories) {
- var ret, self;
- if (levels === undefined) {
- levels = '';
- this._levels = [];
- }
- else {
- this._levels=levels.toLowerCase().split(/[\s,]+/);
- }
- if (categories === undefined) {
- categories = '';
- this._categories = [];
- }
- else {
- this._categories=categories.toLowerCase().split(/[\s,]+/);
- }
-
-
- self = this;
- if(php.empty(levels) && php.empty(categories)) {
- return this._logs;
- }
- else if(php.empty(levels)) {
-
- return Yii.filter(this._logs,function(value, k, arr) {
- var matched = false, cat = value[2].toLowerCase(), c;
- Yii.forEach(self._categories, function(i, category) {
- if(cat===category || ((c=php.rtrim(category,'.*'))!==category && php.strpos(cat,c)===0)) {
- matched = true;
- return false;
- }
- });
- return matched ? value : false;
- });
-
- }
- else if(php.empty(categories)) {
- return Yii.filter(this._logs,function(value, k, arr) {
- var matched = false, matchLevel = value[1].toLowerCase();
- Yii.forEach(self._levels, function(i, level) {
- if (level === matchLevel) {
- matched = true;
- return false;
- }
- });
- return matched ? value : false;
- });
- }
- else {
- return Yii.filter(Yii.filter(this._logs,function(value, k, arr) {
- var matched = false, cat = value[2].toLowerCase(), c;
- Yii.forEach(self._categories, function(i, category) {
- if(cat===category || ((c=php.rtrim(category,'.*'))!==category && php.strpos(cat,c)===0)) {
- matched = true;
- return false;
- }
- });
- return matched ? value : false;
- }), function(value, k, arr) {
- var matched = false, matchLevel = value[1].toLowerCase();
- Yii.forEach(self._levels, function(i, level) {
- if (level === matchLevel) {
- matched = true;
- return false;
- }
- });
- return matched ? value : false;
- });
-
- }
- };
- /**
- * Filter function used by {@link getLogs}
- * @param {Array} value element to be filtered
- * @returns {Array} valid log, false if not.
- */
- Yii.CLogger.prototype.filterByCategory = function (value) {
- var i, cat, category, c;
- for (i in this._categories) {
- if (this._categories.hasOwnProperty(i)) {
- category = this._categories[i];
- cat=value[2].toLowerCase();
- if(cat===category || ((c=php.rtrim(category,'.*'))!==category && php.strpos(cat,c)===0)) {
- return value;
- }
- }
- }
- return false;
- };
- /**
- * Filter function used by {@link getLogs}
- * @param {Array} value element to be filtered
- * @returns {Array} valid log, false if not.
- */
- Yii.CLogger.prototype.filterByLevel = function (value) {
- var matched = false, matchLevel = value[1].toLowerCase();
-
- Yii.forEach(this._levels, function(i, level) {
- console.log(level);
- if (level === matchLevel) {
- matched = true;
- return false;
- }
- });
- return matched ? value : false;
- };
- /**
- * Returns the total time for serving the current request.
- * This method calculates the difference between now and the timestamp
- * defined by constant YII_BEGIN_TIME.
- * To estimate the execution time more accurately, the constant should
- * be defined as early as possible (best at the beginning of the entry script.)
- * @returns {Float} the total time for serving the current request.
- */
- Yii.CLogger.prototype.getExecutionTime = function () {
- return php.microtime(true)-YII_BEGIN_TIME;
- };
- /**
- * Not Available in JavaScript, always returns 0
- * @returns {Integer} memory usage of the application (in bytes).
- */
- Yii.CLogger.prototype.getMemoryUsage = function () {
- return 0;
- };
- /**
- * Returns the profiling results.
- * The results may be filtered by token and/or category.
- * If no filter is specified, the returned results would be an array with each element
- * being array($token,$category,$time).
- * If a filter is specified, the results would be an array of timings.
- * @param {String} token token filter. Defaults to null, meaning not filtered by token.
- * @param {String} category category filter. Defaults to null, meaning not filtered by category.
- * @param {Boolean} refresh whether to refresh the internal timing calculations. If false,
- * only the first time calling this method will the timings be calculated internally.
- * @returns {Array} the profiling results.
- * @since 1.0.6
- */
- Yii.CLogger.prototype.getProfilingResults = function (token, category, refresh) {
- var results, i, timing;
- if (token === undefined) {
- token = null;
- }
- if (category === undefined) {
- category = null;
- }
- if (refresh === undefined) {
- refresh = false;
- }
- if(this._timings===null || refresh) {
- this.calculateTimings();
- }
- if(token===null && category===null) {
- return this._timings;
- }
- results=[];
- for (i in this._timings) {
- if (this._timings.hasOwnProperty(i)) {
- timing = this._timings[i];
- if((category===null || timing[1]===category) && (token===null || timing[0]===token)) {
- results.push(timing[2]);
- }
- }
- }
- return results;
- };
- Yii.CLogger.prototype.calculateTimings = function () {
- var stack, i, log, message, level, category, timestamp, token, last, delta, now;
- this._timings=[];
- stack=[];
- for (i in this._logs) {
- if (this._logs.hasOwnProperty(i)) {
- log = this._logs[i];
- if(log[1]!==Yii.CLogger.prototype.LEVEL_PROFILE) {
- continue;
- }
- message = log[0];
- level = log[1];
- category = log[2];
- timestamp = log[3];
- if(!php.strncasecmp(message,'begin:',6)) {
- log[0]=message.slice(6);
- stack.push(log);
- }
- else if(!php.strncasecmp(message,'end:',4)) {
- token=message.slice(4);
- if((last=php.array_pop(stack))!==null && last[0]===token) {
- delta=log[3]-last[3];
- this._timings.push([message,category,delta]);
- }
- else {
- throw new Yii.CException(Yii.t('yii','CProfileLogRoute found a mismatching code block "{token}". Make sure the calls to Yii::beginProfile() and Yii::endProfile() be properly nested.',
- {'{token}':token}));
- }
- }
- }
- }
- now=php.microtime(true);
- while((last=php.array_pop(stack))!==null) {
- delta=now-last[3];
- this._timings.push([last[0],last[2],delta]);
- }
- };
- /**
- * Removes all recorded messages from the memory.
- * This method will raise an {@link onFlush} event.
- * The attached event handlers can process the log messages before they are removed.
- * @param {Boolean} dumpLogs whether to process the logs
- * @since 1.1.0
- */
- Yii.CLogger.prototype.flush = function (dumpLogs) {
- if (dumpLogs === undefined) {
- dumpLogs = false;
- }
- this.onFlush(new Yii.CEvent(this, {'dumpLogs':dumpLogs}));
- this._logs=[];
- this._logCount=0;
- };
- /**
- * Raises an <code>onFlush</code> event.
- * @param {Yii.CEvent} event the event parameter
- * @since 1.1.0
- */
- Yii.CLogger.prototype.onFlush = function (event) {
- this.raiseEvent('onFlush', event);
- }/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CProfileLogRoute displays the profiling results in Web page.
- *
- * The profiling is done by calling {@link YiiBase::beginProfile()} and {@link YiiBase::endProfile()},
- * which marks the begin and end of a code block.
- *
- * CProfileLogRoute supports two types of report by setting the {@link setReport report} property:
- * <ul>
- * <li>summary: list the execution time of every marked code block</li>
- * <li>callstack: list the mark code blocks in a hierarchical view reflecting their calling sequence.</li>
- * </ul>
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CProfileLogRoute.php 3001 2011-02-24 16:42:44Z alexander.makarow $
- * @package system.logging
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CWebLogRoute
- */
- Yii.CProfileLogRoute = function CProfileLogRoute () {
- };
- Yii.CProfileLogRoute.prototype = new Yii.CWebLogRoute();
- Yii.CProfileLogRoute.prototype.constructor = Yii.CProfileLogRoute;
- /**
- * @var {Boolean} whether to aggregate results according to profiling tokens.
- * If false, the results will be aggregated by categories.
- * Defaults to true. Note that this property only affects the summary report
- * that is enabled when {@link report} is 'summary'.
- * @since 1.0.6
- */
- Yii.CProfileLogRoute.prototype.groupByToken = true;
- /**
- * @var {String} type of profiling report to display
- */
- Yii.CProfileLogRoute.prototype._report = 'summary';
- /**
- * Initializes the route.
- * This method is invoked after the route is created by the route manager.
- */
- Yii.CProfileLogRoute.prototype.init = function () {
-
- this.levels=Yii.CLogger.prototype.LEVEL_PROFILE;
- };
- /**
- * @returns {String} the type of the profiling report to display. Defaults to 'summary'.
- */
- Yii.CProfileLogRoute.prototype.getReport = function () {
- return this._report;
- };
- /**
- * @param {String} value the type of the profiling report to display. Valid values include 'summary' and 'callstack'.
- */
- Yii.CProfileLogRoute.prototype.setReport = function (value) {
- if(value==='summary' || value==='callstack') {
- this._report=value;
- }
- else {
- throw new Yii.CException(Yii.t('yii','CProfileLogRoute.report "{report}" is invalid. Valid values include "summary" and "callstack".',
- {'{report}':value}));
- }
- };
- /**
- * Displays the log messages.
- * @param {Array} logs list of log messages
- */
- Yii.CProfileLogRoute.prototype.processLogs = function (logs) {
- var app;
- app=Yii.app();
-
- if(!(app instanceof Yii.CWebApplication) || app.getRequest().getIsAjaxRequest()) {
- return;
- }
-
- if(this.getReport()==='summary') {
- this.displaySummary(logs);
- }
- else {
- this.displayCallstack(logs);
- }
- };
- /**
- * Displays the callstack of the profiling procedures for display.
- * @param {Array} logs list of logs
- */
- Yii.CProfileLogRoute.prototype.displayCallstack = function (logs) {
- var stack, results, n, i, log, message, token, last, delta, now;
- stack=[];
- results={};
- n=0;
- for (i in logs) {
- if (logs.hasOwnProperty(i)) {
- log = logs[i];
- if(log[1]!==Yii.CLogger.prototype.LEVEL_PROFILE) {
- continue;
- }
- message=log[0];
- if(!php.strncasecmp(message,'begin:',6)){
- log[0]=message.slice(6);
- log[4]=n;
- stack.push(log);
- n++;
- }
- else if(!php.strncasecmp(message,'end:',4)) {
- token=message.slice(4);
- if((last=php.array_pop(stack))!==null && last[0]===token) {
- delta=log[3]-last[3];
- results[last[4]]=[token,delta,php.count(stack)];
- }
- else {
- throw new Yii.CException(Yii.t('yii','CProfileLogRoute found a mismatching code block "{token}". Make sure the calls to Yii::beginProfile() and Yii::endProfile() be properly nested.',
- {'{token}':token}));
- }
- }
- }
- }
- // remaining entries should be closed here
- now=php.microtime(true);
- while((last=php.array_pop(stack))!==null) {
- results[last[4]]=[last[0],now-last[3],php.count(stack)];
- }
- php.ksort(results);
- this.render('profile-callstack',results);
- };
- /**
- * Displays the summary report of the profiling result.
- * @param {Array} logs list of logs
- */
- Yii.CProfileLogRoute.prototype.displaySummary = function (logs) {
- var stack, i, log, message, token, last, delta, results = {}, now, entries, func, data;
- stack=[];
- for (i in logs) {
- if (logs.hasOwnProperty(i)) {
-
- log = logs[i];
-
- if(log[1]!==Yii.CLogger.prototype.LEVEL_PROFILE) {
- continue;
- }
- message=log[0];
-
- if(!php.strncasecmp(message,'begin:',6)) {
- log[0]=message.slice(6);
- stack.push(log);
- }
- else if(!php.strncasecmp(message,'end:',4)) {
- token=message.slice(4);
-
- if((last=php.array_pop(stack))!==null && last[0]===token) {
- delta=log[3]-last[3];
- if(!this.groupByToken) {
- token=log[2];
- }
- if(results[token] !== undefined) {
-
- results[token]=this.aggregateResult(results[token],delta);
- }
- else {
- results[token]=[token,1,delta,delta,delta];
- }
- }
- else {
-
- throw new Yii.CException(Yii.t('yii','CProfileLogRoute found a mismatching code block "{token}". Make sure the calls to Yii::beginProfile() and Yii::endProfile() be properly nested.',
- {'{token}':token}));
- }
- }
- }
- }
-
- now=php.microtime(true);
- while((last=php.array_pop(stack))!==null) {
- delta=now-last[3];
- token=this.groupByToken ? last[0] : last[2];
- if(results[token] !== undefined) {
- results[token]=this.aggregateResult(results[token],delta);
- }
- else {
- results[token]=[token,1,delta,delta,delta];
- }
- }
- entries=php.array_values(results);
- func = function(a,b) {
- return a[4] < b[4] ? 1 : 0;
- };
- php.usort(entries,func);
- data = {
- time: php.sprintf('%0.5f',Yii.getLogger().getExecutionTime()),
- entries: []
- };
-
- Yii.forEach(entries, function(k, entry) {
- data.entries.push({
- 'proc': Yii.CHtml.encode(entry[0]),
- 'count': php.sprintf('%5d',entry[1]),
- 'min': php.sprintf('%0.5f',entry[2]),
- 'max': php.sprintf('%0.5f',entry[3]),
- 'total': php.sprintf('%0.5f',entry[4]),
- 'average': php.sprintf('%0.5f',entry[4] / entry[1])
- });
- });
- if (this.showInFireBug && window['console'] !== undefined) {
- if (console.group !== undefined) {
- console.group("Profiling Summary Report");
- }
- console.log(" count total average min max ");
- Yii.forEach(data.entries, function(k, entry) {
- console.log(" " + entry.count + " " + entry.total + " " + entry.average + " " + entry.min + " " + entry.max + " " + entry.proc);
- });
- if (console.group !== undefined) {
- console.groupEnd();
- }
- }
- else {
- this.render('profile-summary',data);
- }
- };
- /**
- * Aggregates the report result.
- * @param {Array} result log result for this code block
- * @param {Float} delta time spent for this code block
- */
- Yii.CProfileLogRoute.prototype.aggregateResult = function (result, delta) {
- var token, calls, min, max, total;
- token = result[0];
- calls = result[1];
- min = result[2];
- max = result[3];
- total = result[4];
- if(delta<min) {
- min=delta;
- }
- else if(delta>max) {
- max=delta;
- }
- calls++;
- total+=delta;
- return [token,calls,min,max,total];
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CDateTimeParser converts a date/time string to a UNIX timestamp according to the specified pattern.
- *
- * The following pattern characters are recognized:
- * <pre>
- * Pattern | Description
- * ----------------------------------------------------
- * d | Day of month 1 to 31, no padding
- * dd | Day of month 01 to 31, zero leading
- * M | Month digit 1 to 12, no padding
- * MM | Month digit 01 to 12, zero leading
- * yy | 2 year digit, e+g+, 96, 05
- * yyyy | 4 year digit, e+g+, 2005
- * h | Hour in 0 to 23, no padding
- * hh | Hour in 00 to 23, zero leading
- * H | Hour in 0 to 23, no padding
- * HH | Hour in 00 to 23, zero leading
- * m | Minutes in 0 to 59, no padding
- * mm | Minutes in 00 to 59, zero leading
- * s | Seconds in 0 to 59, no padding
- * ss | Seconds in 00 to 59, zero leading
- * a | AM or PM, case-insensitive (since version 1.1.5)
- * ----------------------------------------------------
- * </pre>
- * All other characters must appear in the date string at the corresponding positions.
- *
- * For example, to parse a date string '21/10/2008', use the following:
- * <pre>
- * timestamp=Yii.CDateTimeParser.parse('21/10/2008','dd/MM/yyyy');
- * </pre>
- *
- * To format a timestamp to a date string, please use {@link CDateFormatter}.
- *
- * @originalAuthor Wei Zhuo <weizhuo[at]gmail[dot]com>
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CDateTimeParser.php 2928 2011-02-01 17:41:51Z alexander.makarow $
- * @package system.utils
- * @since 1.0
- * @author Charles Pick
- * @class
- */
- Yii.CDateTimeParser = {
-
- };
- /**
- * Converts a date string to a timestamp.
- * @param {String} value the date string to be parsed
- * @param {String} pattern the pattern that the date string is following
- * @param {Array} defaults the default values for year, month, day, hour, minute and second.
- * The default values will be used in case when the pattern doesn't specify the
- * corresponding fields. For example, if the pattern is 'MM/dd/yyyy' and this
- * parameter is array('minute'=>0, 'second'=>0), then the actual minute and second
- * for the parsing result will take value 0, while the actual hour value will be
- * the current hour obtained by date('H'). This parameter has been available since version 1.1.5.
- * @returns {Integer} timestamp for the date string. False if parsing fails.
- */
- Yii.CDateTimeParser.parse = function (value, pattern, defaults) {
- var tokens, i, n, j, token, year, month, day, hour, minute, second, ampm, tn;
- if (pattern === undefined) {
- pattern = 'MM/dd/yyyy';
- }
- if (defaults === undefined) {
- defaults = [];
- }
- tokens=this.tokenize(pattern);
- i=0;
- n=php.strlen(value);
- for (j in tokens)
- {
- if (tokens.hasOwnProperty(j)) {
- token = tokens[j];
- switch(token)
- {
- case 'yyyy':
- if((year=this.parseInteger(value,i,4,4))===false) {
- return false;
- }
- i+=4;
- break;
- case 'yy':
- if((year=this.parseInteger(value,i,1,2))===false) {
- return false;
- }
- i+=php.strlen(year);
- break;
- case 'MM':
- if((month=this.parseInteger(value,i,2,2))===false) {
- return false;
- }
- i+=2;
- break;
- case 'M':
- if((month=this.parseInteger(value,i,1,2))===false) {
- return false;
- }
- i+=php.strlen(month);
- break;
- case 'dd':
- if((day=this.parseInteger(value,i,2,2))===false) {
- return false;
- }
- i+=2;
- break;
- case 'd':
- if((day=this.parseInteger(value,i,1,2))===false) {
- return false;
- }
- i+=php.strlen(day);
- break;
- case 'h':
- case 'H':
- if((hour=this.parseInteger(value,i,1,2))===false) {
- return false;
- }
- i+=php.strlen(hour);
- break;
- case 'hh':
- case 'HH':
- if((hour=this.parseInteger(value,i,2,2))===false) {
- return false;
- }
- i+=2;
- break;
- case 'm':
- if((minute=this.parseInteger(value,i,1,2))===false) {
- return false;
- }
- i+=php.strlen(minute);
- break;
- case 'mm':
- if((minute=this.parseInteger(value,i,2,2))===false) {
- return false;
- }
- i+=2;
- break;
- case 's':
- if((second=this.parseInteger(value,i,1,2))===false) {
- return false;
- }
- i+=php.strlen(second);
- break;
- case 'ss':
- if((second=this.parseInteger(value,i,2,2))===false) {
- return false;
- }
- i+=2;
- break;
- case 'a':
- if((ampm=this.parseAmPm(value,i))===false) {
- return false;
- }
- if(hour !== undefined)
- {
- if(hour==12 && ampm==='am') {
- hour=0;
- }
- else if(hour<12 && ampm==='pm') {
- hour+=12;
- }
- }
- i+=2;
- break;
- default:
- tn=php.strlen(token);
- if(i>=n || value.slice(i, tn)!==token) {
- return false;
- }
- i+=tn;
- break;
- }
- }
- }
- if(i<n) {
- return false;
- }
- if(year === undefined) {
- year=defaults.year !== undefined ? defaults.year : php.date('Y');
- }
- if(month === undefined) {
- month=defaults.month !== undefined ? defaults.month : php.date('n');
- }
- if(day === undefined) {
- day=defaults.day !== undefined ? defaults.day : php.date('j');
- }
- if(php.strlen(year)===2) {
- if(year>=70) {
- year+=1900;
- }
- else {
- year+=2000;
- }
- }
- year=Number(year);
- month=Number(month);
- day=Number(day);
- if(hour === undefined && minute === undefined && second === undefined && defaults.hour === undefined && defaults.minute === undefined && defaults.second === undefined) {
- hour=minute=second=0;
- }
- else {
- if(hour === undefined) {
- hour=defaults.hour !== undefined ? defaults.hour : php.date('H');
- }
- if(minute === undefined) {
- minute=defaults.minute !== undefined ? defaults.minute : php.date('i');
- }
- if(second === undefined) {
- second=defaults.second !== undefined ? defaults.second : php.date('s');
- }
- hour=Number(hour);
- minute=Number(minute);
- second=Number(second);
- }
- if(Yii.CTimestamp.isValidDate(year,month,day) && Yii.CTimestamp.isValidTime(hour,minute,second)) {
- return Yii.CTimestamp.getTimestamp(hour,minute,second,month,day,year);
- }
- else {
- return false;
- }
- };
- Yii.CDateTimeParser.tokenize = function (pattern) {
- var n, tokens, c0, start, i, c;
- if(!(n=php.strlen(pattern))) {
- return [];
- }
- tokens=[];
- for(c0=pattern[0],start=0,i=1;i<n;++i) {
- if((c=pattern[i])!==c0) {
- tokens.push(pattern.slice(start, i-start));
- c0=c;
- start=i;
- }
- }
- tokens.push(pattern.slice(start, n-start));
- return tokens;
- };
- Yii.CDateTimeParser.parseInteger = function (value, offset, minLength, maxLength) {
- var len, v;
- for(len=maxLength;len>=minLength;--len) {
- v=value.slice(offset, len);
- if(php.ctype_digit(v) && php.strlen(v)>=minLength) {
- return v;
- }
- }
- return false;
- };
- Yii.CDateTimeParser.parseAmPm = function (value, offset) {
- var v;
- v=value.slice(offset, 2).toLowerCase();
- return v==='am' || v==='pm' ? v : false;
- }/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CFormatter provides a set of commonly used data formatting methods.
- *
- * The formatting methods provided by CFormatter are all named in the form of <code>formatXyz</code>.
- * The behavior of some of them may be configured via the properties of CFormatter. For example,
- * by configuring {@link dateFormat}, one may control how {@link formatDate} formats the value into a date string.
- *
- * For convenience, CFormatter also implements the mechanism of calling formatting methods with their shortcuts (called types).
- * In particular, if a formatting method is named <code>formatXyz</code>, then its shortcut method is <code>xyz</code>
- * (case-insensitive). For example, calling <code>$formatter->date($value)</code> is equivalent to calling
- * <code>$formatter->formatDate($value)</code>.
- *
- * Currently, the following types are recognizable:
- * <ul>
- * <li>raw: the attribute value will not be changed at all.</li>
- * <li>text: the attribute value will be HTML-encoded when rendering.</li>
- * <li>ntext: the {@link formatNtext} method will be called to format the attribute value as a HTML-encoded plain text with newlines converted as the HTML <br /> tags.</li>
- * <li>html: the attribute value will be purified and then returned.</li>
- * <li>date: the {@link formatDate} method will be called to format the attribute value as a date.</li>
- * <li>time: the {@link formatTime} method will be called to format the attribute value as a time.</li>
- * <li>datetime: the {@link formatDatetime} method will be called to format the attribute value as a date with time.</li>
- * <li>boolean: the {@link formatBoolean} method will be called to format the attribute value as a boolean display.</li>
- * <li>number: the {@link formatNumber} method will be called to format the attribute value as a number display.</li>
- * <li>email: the {@link formatEmail} method will be called to format the attribute value as a mailto link.</li>
- * <li>image: the {@link formatImage} method will be called to format the attribute value as an image tag where the attribute value is the image URL.</li>
- * <li>url: the {@link formatUrl} method will be called to format the attribute value as a hyperlink where the attribute value is the URL.</li>
- * </ul>
- *
- * By default, {@link CApplication} registers {@link CFormatter} as an application component whose ID is 'format'.
- * Therefore, one may call <code>Yii::app()->format->boolean(1)</code>.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CFormatter.php 2799 2011-01-01 19:31:13Z qiang.xue $
- * @package system.utils
- * @since 1.1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CApplicationComponent
- */
- Yii.CFormatter = function CFormatter() {
- };
- Yii.CFormatter.prototype = new Yii.CApplicationComponent();
- Yii.CFormatter.prototype.constructor = Yii.CFormatter;
- Yii.CFormatter.prototype._htmlPurifier = null;
- /**
- * @var {String} the format string to be used to format a date using PHP date() function. Defaults to 'Y/m/d'.
- */
- Yii.CFormatter.prototype.dateFormat = 'Y/m/d';
- /**
- * @var {String} the format string to be used to format a time using PHP date() function. Defaults to 'h:i:s A'.
- */
- Yii.CFormatter.prototype.timeFormat = 'h:i:s A';
- /**
- * @var {String} the format string to be used to format a date and time using PHP date() function. Defaults to 'Y/m/d h:i:s A'.
- */
- Yii.CFormatter.prototype.datetimeFormat = 'Y/m/d h:i:s A';
- /**
- * @var {Array} the format used to format a number with PHP number_format() function.
- * Three elements may be specified: "decimals", "decimalSeparator" and "thousandSeparator". They
- * correspond to the number of digits after the decimal point, the character displayed as the decimal point,
- * and the thousands separator character.
- */
- Yii.CFormatter.prototype.numberFormat = {
- 'decimals':null,
- 'decimalSeparator':null,
- 'thousandSeparator':null
- };
- /**
- * @var {Array} the text to be displayed when formatting a boolean value. The first element corresponds
- * to the text display for false, the second element for true. Defaults to <code>array('No', 'Yes')</code>.
- */
- Yii.CFormatter.prototype.booleanFormat = ['No','Yes'];
- /**
- * Calls the format method when its shortcut is invoked.
- * This is a PHP magic method that we override to implement the shortcut format methods.
- * @param {String} name the method name
- * @param {Array} parameters method parameters
- * @returns {Mixed} the method return value
- */
- Yii.CFormatter.prototype.call = function (name, parameters) {
- if(php.method_exists(this,'format'+name)) {
- return php.call_user_func_array([this,'format'+name],parameters);
- }
- else {
- return parent.call(name,parameters);
- }
- };
- /**
- * Formats a value based on the given type.
- * @param {Mixed} value the value to be formatted
- * @param {String} type the data type. This must correspond to a format method available in CFormatter.
- * For example, we can use 'text' here because there is method named {@link formatText}.
- * @returns {String} the formatted data
- */
- Yii.CFormatter.prototype.format = function (value, type) {
- var method;
- method='format'+php.ucfirst(type);
- if(php.method_exists(this,method)) {
- return this[method](value);
- }
- else {
- throw new Yii.CException(Yii.t('yii','Unknown type "{type}".',{'{type}':type}));
- }
- };
- /**
- * Formats the value as is without any formatting.
- * This method simply returns back the parameter without any format.
- * @param {Mixed} value the value to be formatted
- * @returns {String} the formatted result
- */
- Yii.CFormatter.prototype.formatRaw = function (value) {
- return value;
- };
- /**
- * Formats the value as a HTML-encoded plain text.
- * @param {Mixed} value the value to be formatted
- * @returns {String} the formatted result
- */
- Yii.CFormatter.prototype.formatText = function (value) {
- return Yii.CHtml.encode(value);
- };
- /**
- * Formats the value as a HTML-encoded plain text and converts newlines with HTML br tags.
- * @param {Mixed} value the value to be formatted
- * @returns {String} the formatted result
- */
- Yii.CFormatter.prototype.formatNtext = function (value) {
- return php.nl2br(Yii.CHtml.encode(value));
- };
- /**
- * Formats the value as HTML text without any encoding.
- * @param {Mixed} value the value to be formatted
- * @returns {String} the formatted result
- */
- Yii.CFormatter.prototype.formatHtml = function (value) {
- return this.getHtmlPurifier().purify(value);
- };
- /**
- * Formats the value as a date.
- * @param {Mixed} value the value to be formatted
- * @returns {String} the formatted result
- * @see dateFormat
- */
- Yii.CFormatter.prototype.formatDate = function (value) {
- return php.date(this.dateFormat,value);
- };
- /**
- * Formats the value as a time.
- * @param {Mixed} value the value to be formatted
- * @returns {String} the formatted result
- * @see timeFormat
- */
- Yii.CFormatter.prototype.formatTime = function (value) {
- return php.date(this.timeFormat,value);
- };
- /**
- * Formats the value as a date and time.
- * @param {Mixed} value the value to be formatted
- * @returns {String} the formatted result
- * @see datetimeFormat
- */
- Yii.CFormatter.prototype.formatDatetime = function (value) {
- return php.date(this.datetimeFormat,value);
- };
- /**
- * Formats the value as a boolean.
- * @param {Mixed} value the value to be formatted
- * @returns {String} the formatted result
- * @see trueText
- * @see falseText
- */
- Yii.CFormatter.prototype.formatBoolean = function (value) {
- return value ? this.booleanFormat[1] : this.booleanFormat[0];
- };
- /**
- * Formats the value as a mailto link.
- * @param {Mixed} value the value to be formatted
- * @returns {String} the formatted result
- */
- Yii.CFormatter.prototype.formatEmail = function (value) {
- return Yii.CHtml.mailto(value);
- };
- /**
- * Formats the value as an image tag.
- * @param {Mixed} value the value to be formatted
- * @returns {String} the formatted result
- */
- Yii.CFormatter.prototype.formatImage = function (value) {
- return Yii.CHtml.image(value);
- };
- /**
- * Formats the value as a hyperlink.
- * @param {Mixed} value the value to be formatted
- * @returns {String} the formatted result
- */
- Yii.CFormatter.prototype.formatUrl = function (value) {
- var url;
- url=value;
- if(php.strpos(url,'http://')!==0 && php.strpos(url,'https://')!==0) {
- url='http://'+url;
- }
- return Yii.CHtml.link(Yii.CHtml.encode(value),url);
- };
- /**
- * Formats the value as a number using PHP number_format() function.
- * @param {Mixed} value the value to be formatted
- * @returns {String} the formatted result
- * @see numberFormat
- */
- Yii.CFormatter.prototype.formatNumber = function (value) {
- return php.number_format(value,this.numberFormat['decimals'],this.numberFormat['decimalSeparator'],this.numberFormat['thousandSeparator']);
- };
- /**
- * @returns {Yii.CHtmlPurifier} the HTML purifier instance
- */
- Yii.CFormatter.prototype.getHtmlPurifier = function () {
- if(this._htmlPurifier===null) {
- this._htmlPurifier=new Yii.CHtmlPurifier();
- }
- return this._htmlPurifier;
- }/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CTimestamp represents a timestamp.
- *
- * Part of this class was adapted from the ADOdb Date Library
- * {@link http://phplens.com/phpeverywhere/ ADOdb abstraction library}.
- * The original source code was released under both BSD and GNU Lesser GPL
- * library license, with the following copyright notice:
- * Copyright (c) 2000, 2001, 2002, 2003, 2004 John Lim
- * All rights reserved.
- *
- * This class is provided to support UNIX timestamp that is beyond the range
- * of 1901-2038 on Unix and1970-2038 on Windows. Except {@link getTimestamp},
- * all other methods in this class can work with the extended timestamp range.
- * For {@link getTimestamp}, because it is merely a wrapper of
- * {@link mktime http://php.net/manual/en/function.mktime.php}, it may still
- * be subject to the limit of timestamp range on certain platforms. Please refer
- * to the PHP manual for more information.
- *
- * @originalAuthor Wei Zhuo <weizhuo[at]gmail[dot]com>
- * @version $Id: CTimestamp.php 3046 2011-03-12 01:48:15Z qiang.xue $
- * @package system.utils
- * @since 1.0
- * @author Charles Pick
- * @class
- */
- Yii.CTimestamp = {
- };
- /**
- * Gets day of week, 0 = Sunday,... 6=Saturday.
- * Algorithm from PEAR::Date_Calc
- * @param {Integer} year year
- * @param {Integer} month month
- * @param {Integer} day day
- * @returns {Integer} day of week
- */
- Yii.CTimestamp.getDayofWeek = function (year, month, day) {
- var greg_correction;
- /*
- Pope Gregory removed 10 days - October 5 to October 14 - from the year 1582 and
- proclaimed that from that time onwards 3 days would be dropped from the calendar
- every 400 years.
- Thursday, October 4, 1582 (Julian) was followed immediately by Friday, October 15, 1582 (Gregorian).
- */
- if (year <= 1582) {
- if (year < 1582 || (year == 1582 && (month < 10 || (month == 10 && day < 15)))) {
- greg_correction = 3;
- }
- else {
- greg_correction = 0;
- }
- }
- else {
- greg_correction = 0;
- }
- if(month > 2) {
- month -= 2;
- }
- else {
- month += 10;
- year--;
- }
- day = php.floor((13 * month - 1) / 5) +
- day + (year % 100) +
- php.floor((year % 100) / 4) +
- php.floor((year / 100) / 4) - 2 *
- php.floor(year / 100) + 77 + greg_correction;
- return day - 7 * php.floor(day / 7);
- };
- /**
- * Checks for leap year, returns true if it is. No 2-digit year check. Also
- * handles julian calendar correctly.
- * @param {Integer} year year to check
- * @returns {Boolean} true if is leap year
- */
- Yii.CTimestamp.isLeapYear = function (year) {
- year = this.digitCheck(year);
- if (year % 4 !== 0) {
- return false;
- }
- if (year % 400 === 0) {
- return true;
- }
- // if gregorian calendar (>1582), century not-divisible by 400 is not leap
- else if (year > 1582 && year % 100 === 0 ) {
- return false;
- }
- return true;
- };
- /**
- * Fix 2-digit years. Works for any century.
- * Assumes that if 2-digit is more than 30 years in future, then previous century.
- * @param {Integer} y year
- * @returns {Integer} change two digit year into multiple digits
- */
- Yii.CTimestamp.digitCheck = function (y) {
- var yr, century, c1, c0;
- if (y < 100){
- yr = Number(php.date("Y"));
- century = Number((yr /100));
- if (yr%100 > 50) {
- c1 = century + 1;
- c0 = century;
- } else {
- c1 = century;
- c0 = century - 1;
- }
- c1 *= 100;
- // if 2-digit year is less than 30 years in future, set it to this century
- // otherwise if more than 30 years in future, then we set 2-digit year to the prev century.
- if ((y + c1) < yr+30) { y = y + c1;
- }
- else { y = y + c0*100;
- }
- }
- return y;
- };
- /**
- * Returns 4-digit representation of the year.
- * @param {Integer} y year
- * @returns {Integer} 4-digit representation of the year
- */
- Yii.CTimestamp.get4DigitYear = function (y) {
- return this.digitCheck(y);
- };
- /**
- * @returns {Integer} get local time zone offset from GMT
- */
- Yii.CTimestamp.getGMTDiff = function () {
- var TZ;
- if (TZ !== undefined) { return TZ; }
- TZ = php.mktime(0,0,0,1,2,1970) - php.gmmktime(0,0,0,1,2,1970);
- return TZ;
- };
- /**
- * Returns the getdate() array.
- * @param {Integer} d original date timestamp. False to use the current timestamp.
- * @param {Boolean} fast false to compute the day of the week, default is true
- * @param {Boolean} gmt true to calculate the GMT dates (ignored for now)
- * @returns {Array} an array with date info.
- */
- Yii.CTimestamp.getDate = function (d, fast, gmt) {
- var tz, result;
- if (d === undefined) {
- d = false;
- }
- if (fast === undefined) {
- fast = false;
- }
- if (gmt === undefined) {
- gmt = false;
- }
- result = php.getdate(d);
-
- return result;
- };
- /**
- * Checks to see if the year, month, day are valid combination.
- * @param {Integer} y year
- * @param {Integer} m month
- * @param {Integer} d day
- * @returns {Boolean} true if valid date, semantic check only.
- */
- Yii.CTimestamp.isValidDate = function (y, m, d) {
- return php.checkdate(m, d, y);
- };
- /**
- * Checks to see if the hour, minute and second are valid.
- * @param {Integer} h hour
- * @param {Integer} m minute
- * @param {Integer} s second
- * @param {Boolean} hs24 whether the hours should be 0 through 23 (default) or 1 through 12.
- * @returns {Boolean} true if valid date, semantic check only.
- * @since 1.0.5
- */
- Yii.CTimestamp.isValidTime = function (h, m, s, hs24) {
- if (hs24 === undefined) {
- hs24 = true;
- }
- if(hs24 && (h < 0 || h > 23) || !hs24 && (h < 1 || h > 12)) {
- return false;
- }
- if(m > 59 || m < 0) {
- return false;
- }
- if(s > 59 || s < 0) {
- return false;
- }
- return true;
- };
- /**
- * Formats a timestamp to a date string.
- * @param {String} fmt format pattern
- * @param {Integer} d timestamp
- * @param {Boolean} is_gmt whether this is a GMT timestamp
- * @returns {String} formatted date based on timestamp $d
- */
- Yii.CTimestamp.formatDate = function (fmt, d, is_gmt) {
- var _day_power, arr, year, month, day, hour, min, secs, max, dates, i, gmt, d10, hh;
- if (d === undefined) {
- d = false;
- }
- if (is_gmt === undefined) {
- is_gmt = false;
- }
- if (d === false) {
- return (is_gmt)? php.gmdate(fmt): php.date(fmt);
- }
- // check if number in 32-bit signed range
- if ((php.abs(d) <= 0x7FFFFFFF)) {
- // if windows, must be +ve integer
- if (d >= 0) {
- return (is_gmt)? php.gmdate(fmt,d): php.date(fmt,d);
- }
- }
- _day_power = 86400;
- arr = this.getDate(d,true,is_gmt);
- year = arr.year;
- month = arr.mon;
- day = arr.mday;
- hour = arr.hours;
- min = arr.minutes;
- secs = arr.seconds;
- max = php.strlen(fmt);
- dates = '';
- /*
- at this point, we have the following integer vars to manipulate:
- $year, $month, $day, $hour, $min, $secs
- */
- for (i=0; i < max; i++)
- {
- switch(fmt[i])
- {
- case 'T':
- dates += php.date('T');
- break;
- // YEAR
- case 'L':
- dates += arr.leap ? '1' : '0';
- break;
- case 'r': // Thu, 21 Dec 2000 16:01:07 +0200
- // 4.3.11 uses '04 Jun 2004'
- // 4.3.8 uses ' 4 Jun 2004'
- dates += php.gmdate('D',_day_power*(3+this.getDayOfWeek(year,month,day)))+', ' + (day<10?'0'+day:day) + ' '+php.date('M',php.mktime(0,0,0,month,2,1971))+' '+year+' ';
- if (hour < 10) {
- dates += '0'+hour;
- }
- else {
- dates += hour;
- }
- if (min < 10) {
- dates += ':0'+min;
- }
- else {
- dates += ':'+min;
- }
- if (secs < 10) {
- dates += ':0'+secs;
- }
- else {
- dates += ':'+secs;
- }
- gmt = this.getGMTDiff();
- dates += php.sprintf(' %s%04d',(gmt<=0)?'+':'-',php.abs(gmt)/36);
- break;
- case 'Y':
- dates += year;
- break;
- case 'y':
- dates += year.slice(php.strlen(year)-2, 2);
- break;
- // MONTH
- case 'm':
- if (month<10) {
- dates += '0'+month;
- }
- else {
- dates += month;
- }
- break;
- case 'Q':
- dates += (month+3)>>2;
- break;
- case 'n':
- dates += month;
- break;
- case 'M':
- dates += php.date('M',php.mktime(0,0,0,month,2,1971));
- break;
- case 'F':
- dates += php.date('F',php.mktime(0,0,0,month,2,1971));
- break;
- // DAY
- case 't':
- dates += arr.ndays;
- break;
- case 'z':
- dates += arr.yday;
- break;
- case 'w':
- dates += this.getDayOfWeek(year,month,day);
- break;
- case 'l':
- dates += php.gmdate('l',_day_power*(3+this.getDayOfWeek(year,month,day)));
- break;
- case 'D':
- dates += php.gmdate('D',_day_power*(3+this.getDayOfWeek(year,month,day)));
- break;
- case 'j':
- dates += day;
- break;
- case 'd':
- if (day<10) {
- dates += '0'+day;
- }
- else {
- dates += day;
- }
- break;
- case 'S':
- d10 = day % 10;
- if (d10 == 1) {
- dates += 'st';
- }
- else if (d10 == 2 && day != 12) {
- dates += 'nd';
- }
- else if (d10 == 3) {
- dates += 'rd';
- }
- else {
- dates += 'th';
- }
- break;
- // HOUR
- case 'Z':
- dates += (is_gmt) ? 0 : -this.getGMTDiff();
- break;
- case 'O':
- gmt = (is_gmt) ? 0 : this.getGMTDiff();
- dates += php.sprintf('%s%04d',(gmt<=0)?'+':'-',php.abs(gmt)/36);
- break;
- case 'H':
- if (hour < 10) {
- dates += '0'+hour;
- }
- else {
- dates += hour;
- }
- break;
- case 'h':
- if (hour > 12) {
- hh = hour - 12;
- }
- else {
- if (hour === 0) {
- hh = '12';
- }
- else {
- hh = hour;
- }
- }
- if (hh < 10) {
- dates += '0'+hh;
- }
- else {
- dates += hh;
- }
- break;
- case 'G':
- dates += hour;
- break;
- case 'g':
- if (hour > 12) {
- hh = hour - 12;
- }
- else {
- if (hour === 0) {
- hh = '12';
- }
- else {
- hh = hour;
- }
- }
- dates += hh;
- break;
- // MINUTES
- case 'i':
- if (min < 10) {
- dates += '0'+min;
- }
- else {
- dates += min;
- }
- break;
- // SECONDS
- case 'U':
- dates += d;
- break;
- case 's':
- if (secs < 10) {
- dates += '0'+secs;
- }
- else {
- dates += secs;
- }
- break;
- // AM/PM
- // Note 00:00 to 11:59 is AM, while 12:00 to 23:59 is PM
- case 'a':
- if (hour>=12) {
- dates += 'pm';
- }
- else {
- dates += 'am';
- }
- break;
- case 'A':
- if (hour>=12) {
- dates += 'PM';
- }
- else {
- dates += 'AM';
- }
- break;
- default:
- dates += fmt[i];
- break;
- // ESCAPE
- case "\\":
- i++;
- if (i < max) {
- dates += fmt[i];
- }
- break;
- }
- }
- return dates;
- };
- /**
- * Generates a timestamp.
- * This is the same as the PHP function {@link mktime http://php.net/manual/en/function.mktime.php}.
- * @param {Integer} hr hour
- * @param {Integer} min minute
- * @param {Integer} sec second
- * @param {Integer} mon month
- * @param {Integer} day day
- * @param {Integer} year year
- * @param {Boolean} is_gmt whether this is GMT time. If true, gmmktime() will be used.
- * @returns {Integer|float} a timestamp given a local time.
- */
- Yii.CTimestamp.getTimestamp = function (hr, min, sec, mon, day, year, is_gmt) {
- if (mon === undefined) {
- mon = false;
- }
- if (day === undefined) {
- day = false;
- }
- if (year === undefined) {
- year = false;
- }
- if (is_gmt === undefined) {
- is_gmt = false;
- }
- if (mon === false) {
- return is_gmt? php.gmmktime(hr,min,sec): php.mktime(hr,min,sec);
- }
- return is_gmt ? php.gmmktime(hr,min,sec,mon,day,year) : php.mktime(hr,min,sec,mon,day,year);
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CBooleanValidator validates that the attribute value is either {@link trueValue} or {@link falseValue}.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CBooleanValidator.php 3120 2011-03-25 01:50:48Z qiang.xue $
- * @package system.validators
- * @since 1.0.10
- * @author Charles Pick
- * @class
- * @extends Yii.CValidator
- */
- Yii.CBooleanValidator = function CBooleanValidator() {
- };
- Yii.CBooleanValidator.prototype = new Yii.CValidator();
- Yii.CBooleanValidator.prototype.constructor = Yii.CBooleanValidator;
- /**
- * @var {Mixed} the value representing true status. Defaults to '1'.
- */
- Yii.CBooleanValidator.prototype.trueValue = '1';
- /**
- * @var {Mixed} the value representing false status. Defaults to '0'.
- */
- Yii.CBooleanValidator.prototype.falseValue = '0';
- /**
- * @var {Boolean} whether the comparison to {@link trueValue} and {@link falseValue} is strict.
- * When this is true, the attribute value and type must both match those of {@link trueValue} or {@link falseValue}.
- * Defaults to false, meaning only the value needs to be matched.
- */
- Yii.CBooleanValidator.prototype.strict = false;
- /**
- * @var {Boolean} whether the attribute value can be null or empty. Defaults to true,
- * meaning that if the attribute is empty, it is considered valid.
- */
- Yii.CBooleanValidator.prototype.allowEmpty = true;
- /**
- * Validates the attribute of the object.
- * If there is any error, the error message is added to the object.
- * @param {Yii.CModel} object the object being validated
- * @param {String} attribute the attribute being validated
- */
- Yii.CBooleanValidator.prototype.validateAttribute = function (object, attribute) {
- var value, message;
- value=object.get(attribute);
- if(this.allowEmpty && this.isEmpty(value)) {
- return;
- }
- if(!this.strict && value!=this.trueValue && value!=this.falseValue || this.strict && value!==this.trueValue && value!==this.falseValue) {
- message=this.message!==null?this.message:Yii.t('yii','{attribute} must be either {true} or {false}.');
- this.addError(object,attribute,message,{
- '{true}':this.trueValue,
- '{false}':this.falseValue
- });
- }
- };
- /*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CEmailValidator validates that the attribute value is a valid email address.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CEmailValidator.php 3120 2011-03-25 01:50:48Z qiang.xue $
- * @package system.validators
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CValidator
- */
- Yii.CEmailValidator = function CEmailValidator() {
- };
- Yii.CEmailValidator.prototype = new Yii.CValidator();
- Yii.CEmailValidator.prototype.constructor = Yii.CEmailValidator;
- /**
- * @var {String} the regular expression used to validate the attribute value.
- * @see http://www.regular-expressions.info/email.html
- */
- Yii.CEmailValidator.prototype.pattern = '^[a-zA-Z0-9!#$%&\'*+\\/=?^_`{|}~-]+(?:\\.[a-zA-Z0-9!#$%&\'*+\\/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?$';
- /**
- * @var {String} the regular expression used to validate email addresses with the name part.
- * This property is used only when {@link allowName} is true.
- * @since 1.0.5
- * @see allowName
- */
- Yii.CEmailValidator.prototype.fullPattern = '^[^@]*<[a-zA-Z0-9!#$%&\'*+\\/=?^_`{|}~-]+(?:\\.[a-zA-Z0-9!#$%&\'*+\\/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?>$';
- /**
- * @var {Boolean} whether to allow name in the email address (e.g. "Qiang Xue <qiang.xue@gmail.com>"). Defaults to false.
- * @since 1.0.5
- * @see fullPattern
- */
- Yii.CEmailValidator.prototype.allowName = false;
- /**
- * @var {Boolean} whether the attribute value can be null or empty. Defaults to true,
- * meaning that if the attribute is empty, it is considered valid.
- */
- Yii.CEmailValidator.prototype.allowEmpty = true;
- /**
- * Validates the attribute of the object.
- * If there is any error, the error message is added to the object.
- * @param {Yii.CModel} object the object being validated
- * @param {String} attribute the attribute being validated
- */
- Yii.CEmailValidator.prototype.validateAttribute = function (object, attribute) {
- var value, message;
-
- value=object[attribute];
- if(this.allowEmpty && this.isEmpty(value)) {
- return;
- }
- if(!this.validateValue(value)) {
- message=this.message!==null?this.message:Yii.t('yii','{attribute} is not a valid email address.');
-
- this.addError(object,attribute,message);
- }
- };
- /**
- * Validates a static value to see if it is a valid email.
- * Note that this method does not respect {@link allowEmpty} property.
- * This method is provided so that you can call it directly without going through the model validation rule mechanism.
- * @param {Mixed} value the value to be validated
- * @returns {Boolean} whether the value is a valid email
- * @since 1.1.1
- */
- Yii.CEmailValidator.prototype.validateValue = function (value) {
-
- var valid, re, reFull;
- re = new RegExp(this.pattern);
- reFull = new RegExp(this.fullPattern);
-
- valid=typeof(value) === 'string' && (re.exec(value) || this.allowName && reFull.exec(value));
-
- return valid;
- };
- /*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CInlineValidator represents a validator which is defined as a method in the object being validated.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CInlineValidator.php 2799 2011-01-01 19:31:13Z qiang.xue $
- * @package system.validators
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CValidator
- */
- Yii.CInlineValidator = function CInlineValidator() {
- };
- Yii.CInlineValidator.prototype = new Yii.CValidator();
- Yii.CInlineValidator.prototype.constructor = Yii.CInlineValidator;
- /**
- * @var {String} the name of the validation method defined in the active record class
- */
- Yii.CInlineValidator.prototype.method = null;
- /**
- * @var {Array} additional parameters that are passed to the validation method
- */
- Yii.CInlineValidator.prototype.params = null;
- /**
- * Validates the attribute of the object.
- * If there is any error, the error message is added to the object.
- * @param {Yii.CModel} object the object being validated
- * @param {String} attribute the attribute being validated
- */
- Yii.CInlineValidator.prototype.validateAttribute = function (object, attribute) {
- var method;
- method=this.method;
- object[method](attribute,this.params);
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CNumberValidator validates that the attribute value is a number.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CNumberValidator.php 3120 2011-03-25 01:50:48Z qiang.xue $
- * @package system.validators
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CValidator
- */
- Yii.CNumberValidator = function CNumberValidator() {
- };
- Yii.CNumberValidator.prototype = new Yii.CValidator();
- Yii.CNumberValidator.prototype.constructor = Yii.CNumberValidator;
- /**
- * @var {Boolean} whether the attribute value can only be an integer. Defaults to false.
- */
- Yii.CNumberValidator.prototype.integerOnly = false;
- /**
- * @var {Boolean} whether the attribute value can be null or empty. Defaults to true,
- * meaning that if the attribute is empty, it is considered valid.
- */
- Yii.CNumberValidator.prototype.allowEmpty = true;
- /**
- * @var {Integer|float} upper limit of the number. Defaults to null, meaning no upper limit.
- */
- Yii.CNumberValidator.prototype.max = null;
- /**
- * @var {Integer|float} lower limit of the number. Defaults to null, meaning no lower limit.
- */
- Yii.CNumberValidator.prototype.min = null;
- /**
- * @var {String} user-defined error message used when the value is too big.
- */
- Yii.CNumberValidator.prototype.tooBig = null;
- /**
- * @var {String} user-defined error message used when the value is too small.
- */
- Yii.CNumberValidator.prototype.tooSmall = null;
- /**
- * @var {String} the regular expression for matching integers.
- * @since 1.1.7
- */
- Yii.CNumberValidator.prototype.integerPattern = '^\\s*[+-]?\\d+\\s*$';
- /**
- * @var {String} the regular expression for matching numbers.
- * @since 1.1.7
- */
- Yii.CNumberValidator.prototype.numberPattern = '^\\s*[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?\\s*$';
- /**
- * Validates the attribute of the object.
- * If there is any error, the error message is added to the object.
- * @param {Yii.CModel} object the object being validated
- * @param {String} attribute the attribute being validated
- */
- Yii.CNumberValidator.prototype.validateAttribute = function (object, attribute) {
- var value, message, intRe = new RegExp(this.integerPattern), numRe = new RegExp(this.numberPattern);
- value=String(object[attribute]);
- if(this.allowEmpty && this.isEmpty(value)) {
- return;
- }
- if(this.integerOnly) {
- if(!intRe.exec(value)) {
- message=this.message!==null?this.message:Yii.t('yii','{attribute} must be an integer.');
- this.addError(object,attribute,message);
- }
- }
- else {
- if(!numRe.exec(value)) {
- message=this.message!==null?this.message:Yii.t('yii','{attribute} must be a number.');
- this.addError(object,attribute,message);
- }
- }
- if(this.min!==null && value<this.min) {
- message=this.tooSmall!==null?this.tooSmall:Yii.t('yii','{attribute} is too small (minimum is {min}).');
- this.addError(object,attribute,message,{'{min}':this.min});
- }
- if(this.max!==null && value>this.max) {
- message=this.tooBig!==null?this.tooBig:Yii.t('yii','{attribute} is too big (maximum is {max}).');
- this.addError(object,attribute,message,{'{max}':this.max});
- }
- };
- /*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CRangeValidator validates that the attribute value is among the list (specified via {@link range}).
- * You may invert the validation logic with help of the {@link not} property (available since 1.1.5).
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CRangeValidator.php 3120 2011-03-25 01:50:48Z qiang.xue $
- * @package system.validators
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CValidator
- */
- Yii.CRangeValidator = function CRangeValidator() {
- };
- Yii.CRangeValidator.prototype = new Yii.CValidator();
- Yii.CRangeValidator.prototype.constructor = Yii.CRangeValidator;
- /**
- * @var {Array} list of valid values that the attribute value should be among
- */
- Yii.CRangeValidator.prototype.range = null;
- /**
- * @var {Boolean} whether the comparison is strict (both type and value must be the same)
- */
- Yii.CRangeValidator.prototype.strict = false;
- /**
- * @var {Boolean} whether the attribute value can be null or empty. Defaults to true,
- * meaning that if the attribute is empty, it is considered valid.
- */
- Yii.CRangeValidator.prototype.allowEmpty = true;
- /**
- * @var {Boolean} whether to invert the validation logic. Defaults to false. If set to true,
- * the attribute value should NOT be among the list of values defined via {@link range}.
- * @since 1.1.5
- */
- Yii.CRangeValidator.prototype.not = false;
- /**
- * Validates the attribute of the object.
- * If there is any error, the error message is added to the object.
- * @param {Yii.CModel} object the object being validated
- * @param {String} attribute the attribute being validated
- */
- Yii.CRangeValidator.prototype.validateAttribute = function (object, attribute) {
- var value, message;
- value=object.get(attribute);
-
- if(this.allowEmpty && this.isEmpty(value)) {
- return;
- }
- if(Object.prototype.toString.call(this.range) !== '[object Array]') {
- throw new Yii.CException(Yii.t('yii','The "range" property must be specified with a list of values.'));
- }
- if(!this.not && !php.in_array(value,this.range,this.strict))
- {
- message=this.message!==null?this.message:Yii.t('yii','{attribute} is not in the list.');
- this.addError(object,attribute,message);
- }
- else if(this.not && php.in_array(value,this.range,this.strict))
- {
- message=this.message!==null?this.message:Yii.t('yii','{attribute} is in the list.');
- this.addError(object,attribute,message);
- }
- };
- /*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CRequiredValidator validates that the specified attribute does not have null or empty value.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CRequiredValidator.php 3157 2011-04-02 19:21:06Z qiang.xue $
- * @package system.validators
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CValidator
- */
- Yii.CRequiredValidator = function CRequiredValidator() {
- };
- Yii.CRequiredValidator.prototype = new Yii.CValidator();
- Yii.CRequiredValidator.prototype.constructor = Yii.CRequiredValidator;
- /**
- * @var {Mixed} the desired value that the attribute must have.
- * If this is null, the validator will validate that the specified attribute does not have null or empty value.
- * If this is set as a value that is not null, the validator will validate that
- * the attribute has a value that is the same as this property value.
- * Defaults to null.
- * @since 1.0.10
- */
- Yii.CRequiredValidator.prototype.requiredValue = null;
- /**
- * @var {Boolean} whether the comparison to {@link requiredValue} is strict.
- * When this is true, the attribute value and type must both match those of {@link requiredValue}.
- * Defaults to false, meaning only the value needs to be matched.
- * This property is only used when {@link requiredValue} is not null.
- * @since 1.0.10
- */
- Yii.CRequiredValidator.prototype.strict = false;
- /**
- * Validates the attribute of the object.
- * If there is any error, the error message is added to the object.
- * @param {Yii.CModel} object the object being validated
- * @param {String} attribute the attribute being validated
- */
- Yii.CRequiredValidator.prototype.validateAttribute = function (object, attribute) {
- var value, message;
- value=object.get(attribute);
-
- if(this.requiredValue!==null) {
- if(!this.strict && value!=this.requiredValue || this.strict && value!==this.requiredValue) {
- message=this.message!==null?this.message:Yii.t('yii','{attribute} must be {value}.',
- {'{value}':this.requiredValue});
- this.addError(object,attribute,message);
- }
- }
- else if(this.isEmpty(value,true)) {
- message=this.message!==null?this.message:Yii.t('yii','{attribute} cannot be blank.');
- this.addError(object,attribute,message);
- }
- };
- /*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CTypeValidator verifies if the attribute is of the type specified by {@link type}.
- *
- * The following data types are supported:
- * <ul>
- * <li><b>integer</b> A 32-bit signed integer data type.</li>
- * <li><b>float</b> A double-precision floating point number data type.</li>
- * <li><b>string</b> A string data type.</li>
- * <li><b>array</b> An array value. </li>
- * <li><b>date</b> A date data type.</li>
- * <li><b>time</b> A time data type (available since version 1.0.5).</li>
- * <li><b>datetime</b> A date and time data type (available since version 1.0.5).</li>
- * </ul>
- *
- * For <b>date</b> type, the property {@link dateFormat}
- * will be used to determine how to parse the date string. If the given date
- * value doesn't follow the format, the attribute is considered as invalid.
- *
- * Starting from version 1.1.7, we have a dedicated date validator {@link CDateValidator}.
- * Please consider using this validator to validate a date-typed value.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CTypeValidator.php 3052 2011-03-12 14:27:07Z qiang.xue $
- * @package system.validators
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CValidator
- */
- Yii.CTypeValidator = function CTypeValidator() {
- };
- Yii.CTypeValidator.prototype = new Yii.CValidator();
- Yii.CTypeValidator.prototype.constructor = Yii.CTypeValidator;
- /**
- * @var {String} the data type that the attribute should be. Defaults to 'string'.
- * Valid values include 'string', 'integer', 'float', 'array', 'date', 'time' and 'datetime'.
- * Note that 'time' and 'datetime' have been available since version 1.0.5.
- */
- Yii.CTypeValidator.prototype.type = 'string';
- /**
- * @var {String} the format pattern that the date value should follow. Defaults to 'MM/dd/yyyy'.
- * Please see {@link CDateTimeParser} for details about how to specify a date format.
- * This property is effective only when {@link type} is 'date'.
- */
- Yii.CTypeValidator.prototype.dateFormat = 'MM/dd/yyyy';
- /**
- * @var {String} the format pattern that the time value should follow. Defaults to 'hh:mm'.
- * Please see {@link CDateTimeParser} for details about how to specify a time format.
- * This property is effective only when {@link type} is 'time'.
- * @since 1.0.5
- */
- Yii.CTypeValidator.prototype.timeFormat = 'hh:mm';
- /**
- * @var {String} the format pattern that the datetime value should follow. Defaults to 'MM/dd/yyyy hh:mm'.
- * Please see {@link CDateTimeParser} for details about how to specify a datetime format.
- * This property is effective only when {@link type} is 'datetime'.
- * @since 1.0.5
- */
- Yii.CTypeValidator.prototype.datetimeFormat = 'MM/dd/yyyy hh:mm';
- /**
- * @var {Boolean} whether the attribute value can be null or empty. Defaults to true,
- * meaning that if the attribute is empty, it is considered valid.
- */
- Yii.CTypeValidator.prototype.allowEmpty = true;
- /**
- * Validates the attribute of the object.
- * If there is any error, the error message is added to the object.
- * @param {Yii.CModel} object the object being validated
- * @param {String} attribute the attribute being validated
- */
- Yii.CTypeValidator.prototype.validateAttribute = function (object, attribute) {
- var value, valid, message;
- value=object.get(attribute);
- if(this.allowEmpty && this.isEmpty(value)) {
- return;
- }
- if(this.type==='integer') {
- valid=/^[\-+]?[0-9]+$/.exec(php.trim(value));
- }
- else if(this.type==='float') {
- valid=/^[\-+]?([0-9]*\.)?[0-9]+([eE][\-+]?[0-9]+)?$/.exec(php.trim(value));
- }
- else if(this.type==='date') {
- valid=Yii.CDateTimeParser.parse(value,this.dateFormat,{'month':1,'day':1,'hour':0,'minute':0,'second':0})!==false;
- }
- else if(this.type==='time') {
- valid=Yii.CDateTimeParser.parse(value,this.timeFormat)!==false;
- }
- else if(this.type==='datetime') {
- valid=Yii.CDateTimeParser.parse(value,this.datetimeFormat, {'month':1,'day':1,'hour':0,'minute':0,'second':0})!==false;
- }
- else if(this.type==='array') {
- valid=Object.prototype.toString.call(value) === '[object Array]';
- }
- else {
- return;
- }
- if(!valid) {
- message=this.message!==null?this.message : Yii.t('yii','{attribute} must be {type}.');
- this.addError(object,attribute,message,{'{type}':this.type});
- }
- }/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CUrlValidator validates that the attribute value is a valid http or https URL.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CUrlValidator.php 3120 2011-03-25 01:50:48Z qiang.xue $
- * @package system.validators
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CValidator
- */
- Yii.CUrlValidator = function CUrlValidator() {
-
- };
- Yii.CUrlValidator.prototype = new Yii.CValidator();
- Yii.CUrlValidator.prototype.constructor = Yii.CUrlValidator;
- /**
- * @var {String} the regular expression used to validate the attribute value.
- * Since version 1.1.7 the pattern may contain a {schemes} token that will be replaced
- * by a regular expression which represents the {@see validSchemes}.
- */
- Yii.CUrlValidator.prototype.pattern = '^{schemes}:\\/\\/(([A-Z0-9][A-Z0-9_-]*)(\\.[A-Z0-9][A-Z0-9_-]*)+)';
- /**
- * @var {Array} list of URI schemes which should be considered valid. By default, http and https
- * are considered to be valid schemes.
- * @since 1.1.7
- */
- Yii.CUrlValidator.prototype.validSchemes = ['http','https'];
- /**
- * @var {String} the default URI scheme. If the input doesn't contain the scheme part, the default
- * scheme will be prepended to it (thus changing the input). Defaults to null, meaning a URL must
- * contain the scheme part.
- * @since 1.1.7
- */
- Yii.CUrlValidator.prototype.defaultScheme = null;
- /**
- * @var {Boolean} whether the attribute value can be null or empty. Defaults to true,
- * meaning that if the attribute is empty, it is considered valid.
- */
- Yii.CUrlValidator.prototype.allowEmpty = true;
- /**
- * Validates the attribute of the object.
- * If there is any error, the error message is added to the object.
- * @param {Yii.CModel} object the object being validated
- * @param {String} attribute the attribute being validated
- */
- Yii.CUrlValidator.prototype.validateAttribute = function (object, attribute) {
- var value, message;
- value=object.get(attribute);
- if(this.allowEmpty && this.isEmpty(value)) {
- return;
- }
- if((value=this.validateValue(value))!==false) {
- object[attribute]=value;
- }
- else {
- message=this.message!==null?this.message:Yii.t('yii','{attribute} is not a valid URL.');
- this.addError(object,attribute,message);
- }
- };
- /**
- * Validates a static value to see if it is a valid URL.
- * Note that this method does not respect {@link allowEmpty} property.
- * This method is provided so that you can call it directly without going through the model validation rule mechanism.
- * @param {Mixed} value the value to be validated
- * @returns {Mixed} false if the the value is not a valid URL, otherwise the possibly modified value ({@see defaultScheme})
- * @since 1.1.1
- */
- Yii.CUrlValidator.prototype.validateValue = function (value) {
- var pattern, re;
- if(typeof(value) === 'string') {
- if(this.defaultScheme!==null && php.strpos(value,'://')===false) {
- value=this.defaultScheme+'://'+value;
- }
- if(php.strpos(this.pattern,'{schemes}')!==false) {
- pattern=php.str_replace('{schemes}','('+this.validSchemes.join('|')+')',this.pattern);
- }
- else {
- pattern=this.pattern;
- }
- re = new RegExp(this.pattern,"i");
- if(re.exec(value)) {
- return value;
- }
- }
- return false;
- };
- /*
- * Original script by Josh Fraser (http://www.onlineaspect.com)
- * Continued by Jon Nylander, (jon at pageloom dot com)
- * According to both of us, you are absolutely free to do whatever
- * you want with this code.
- *
- * This code is maintained at bitbucket.org as jsTimezoneDetect.
- */
-
- /**
- * Namespace to hold all the code for timezone detection.
- */
- var jzTimezoneDetector = {};
-
- jzTimezoneDetector.HEMISPHERE_SOUTH = 'SOUTH';
- jzTimezoneDetector.HEMISPHERE_NORTH = 'NORTH';
- jzTimezoneDetector.HEMISPHERE_UNKNOWN = 'N/A';
- jzTimezoneDetector.olson = {};
-
- /**
- * A simple object containing information of utc_offset, which olson timezone key to use,
- * and if the timezone cares about daylight savings or not.
- *
- * @constructor
- * @param {string} offset - for example '-11:00'
- * @param {string} olson_tz - the olson Identifier, such as "America/Denver"
- * @param {boolean} uses_dst - flag for whether the time zone somehow cares about daylight savings.
- */
- jzTimezoneDetector.TimeZone = function (offset, olson_tz, uses_dst) {
- this.utc_offset = offset;
- this.olson_tz = olson_tz;
- this.uses_dst = uses_dst;
- };
-
- /**
- * Prints out the result.
- * But before it does that, it calls this.ambiguity_check.
- */
- jzTimezoneDetector.TimeZone.prototype.display = function() {
- this.ambiguity_check();
- var response_text = '<b>UTC-offset</b>: ' + this.utc_offset + '<br/>';
- response_text += '<b>Zoneinfo key</b>: ' + this.olson_tz + '<br/>';
- response_text += '<b>Zone uses DST</b>: ' + (this.uses_dst ? 'yes' : 'no') + '<br/>';
-
- return response_text;
- };
-
- /**
- * Checks if a timezone has possible ambiguities. I.e timezones that are similar.
- *
- * If the preliminary scan determines that we're in America/Denver. We double check
- * here that we're really there and not in America/Mazatlan.
- *
- * This is done by checking known dates for when daylight savings start for different
- * timezones.
- */
- jzTimezoneDetector.TimeZone.prototype.ambiguity_check = function() {
- var local_ambiguity_list = jzTimezoneDetector.olson.ambiguity_list[this.olson_tz];
-
- if (typeof(local_ambiguity_list) == 'undefined') {
- return;
- }
-
- var length = local_ambiguity_list.length;
-
- for (var i = 0; i < length; i++) {
- var tz = local_ambiguity_list[i];
-
- if (jzTimezoneDetector.date_is_dst(jzTimezoneDetector.olson.dst_start_dates[tz])) {
- this.olson_tz = tz;
- return;
- }
- }
- };
-
- /**
- * Checks whether a given date is in daylight savings time.
- *
- * If the date supplied is after june, we assume that we're checking
- * for southern hemisphere DST.
- *
- * @param {Date} date
- * @returns {boolean}
- */
- jzTimezoneDetector.date_is_dst = function (date) {
- var base_offset, date_offset;
- base_offset = ( (date.getMonth() > 5 ? jzTimezoneDetector.get_june_offset() : jzTimezoneDetector.get_january_offset()) );
- date_offset = jzTimezoneDetector.get_date_offset(date);
-
- return (base_offset - date_offset) !== 0;
- };
-
- /**
- * Gets the offset in minutes from UTC for a certain date.
- *
- * @param date
- * @returns {number}
- */
- jzTimezoneDetector.get_date_offset = function (date) {
- return -date.getTimezoneOffset();
- };
-
- /**
- * This function does some basic calculations to create information about
- * the user's timezone.
- *
- * Returns a primitive object on the format
- * {'utc_offset' : -9, 'dst': 1, hemisphere' : 'north'}
- * where dst is 1 if the region uses daylight savings.
- *
- * @returns {Object}
- */
- jzTimezoneDetector.get_timezone_info = function () {
- var january_offset = jzTimezoneDetector.get_january_offset();
-
- var june_offset = jzTimezoneDetector.get_june_offset();
-
- var diff = january_offset - june_offset;
-
- if (diff < 0) {
- return {'utc_offset' : january_offset,
- 'dst': 1,
- 'hemisphere' : jzTimezoneDetector.HEMISPHERE_NORTH};
- }
- else if (diff > 0) {
- return {'utc_offset' : june_offset,
- 'dst' : 1,
- 'hemisphere' : jzTimezoneDetector.HEMISPHERE_SOUTH};
- }
- return {'utc_offset' : january_offset,
- 'dst': 0,
- 'hemisphere' : jzTimezoneDetector.HEMISPHERE_UNKNOWN};
- };
-
- jzTimezoneDetector.get_january_offset = function () {
- return jzTimezoneDetector.get_date_offset(new Date(2011, 0, 1, 0, 0, 0, 0));
- };
-
- jzTimezoneDetector.get_june_offset = function () {
- return jzTimezoneDetector.get_date_offset(new Date(2011, 5, 1, 0, 0, 0, 0));
- };
-
- /**
- * Uses get_timezone_info() to formulate a key to use in the olson.timezones dictionary.
- *
- * Returns a primitive object on the format:
- * {'timezone': TimeZone, 'key' : 'the key used to find the TimeZone object'}
- *
- * @returns Object
- */
- jzTimezoneDetector.determine_timezone = function () {
- var tz_key, timezone_key_info = jzTimezoneDetector.get_timezone_info(), hemisphere_suffix = '';
-
- if (timezone_key_info.hemisphere == jzTimezoneDetector.HEMISPHERE_SOUTH) {
- hemisphere_suffix = ',s';
- }
-
- tz_key = timezone_key_info.utc_offset + ',' + timezone_key_info.dst + hemisphere_suffix;
-
- return {'timezone' : jzTimezoneDetector.olson.timezones[tz_key], 'key' : tz_key};
- };
-
- /**
- * The keys in this dictionary are comma separated as such:
- *
- * First the offset compared to UTC time in minutes.
- *
- * Then a flag which is 0 if the timezone does not take daylight savings into account and 1 if it does.
- *
- * Thirdly an optional 's' signifies that the timezone is in the southern hemisphere, only interesting for timezones with DST.
- *
- * The values of the dictionary are TimeZone objects.
- */
- jzTimezoneDetector.olson.timezones = {
- '-720,0' : new jzTimezoneDetector.TimeZone('-12:00','Etc/GMT+12', false),
- '-660,0' : new jzTimezoneDetector.TimeZone('-11:00','Pacific/Pago_Pago', false),
- '-600,1' : new jzTimezoneDetector.TimeZone('-11:00','America/Adak',true),
- '-660,1,s' : new jzTimezoneDetector.TimeZone('-11:00','Pacific/Apia', true),
- '-600,0' : new jzTimezoneDetector.TimeZone('-10:00','Pacific/Honolulu', false),
- '-570,0' : new jzTimezoneDetector.TimeZone('-10:30','Pacific/Marquesas',false),
- '-540,0' : new jzTimezoneDetector.TimeZone('-09:00','Pacific/Gambier',false),
- '-540,1' : new jzTimezoneDetector.TimeZone('-09:00','America/Anchorage', true),
- '-480,1' : new jzTimezoneDetector.TimeZone('-08:00','America/Los_Angeles', true),
- '-480,0' : new jzTimezoneDetector.TimeZone('-08:00','Pacific/Pitcairn',false),
- '-420,0' : new jzTimezoneDetector.TimeZone('-07:00','America/Phoenix', false),
- '-420,1' : new jzTimezoneDetector.TimeZone('-07:00','America/Denver', true),
- '-360,0' : new jzTimezoneDetector.TimeZone('-06:00','America/Guatemala', false),
- '-360,1' : new jzTimezoneDetector.TimeZone('-06:00','America/Chicago', true),
- '-360,1,s' : new jzTimezoneDetector.TimeZone('-06:00','Pacific/Easter',true),
- '-300,0' : new jzTimezoneDetector.TimeZone('-05:00','America/Bogota', false),
- '-300,1' : new jzTimezoneDetector.TimeZone('-05:00','America/New_York', true),
- '-270,0' : new jzTimezoneDetector.TimeZone('-04:30','America/Caracas', false),
- '-240,1' : new jzTimezoneDetector.TimeZone('-04:00','America/Halifax', true),
- '-240,0' : new jzTimezoneDetector.TimeZone('-04:00','America/Santo_Domingo', false),
- '-240,1,s' : new jzTimezoneDetector.TimeZone('-04:00','America/Asuncion', true),
- '-210,1' : new jzTimezoneDetector.TimeZone('-03:30','America/St_Johns', true),
- '-180,1' : new jzTimezoneDetector.TimeZone('-03:00','America/Godthab', true),
- '-180,0' : new jzTimezoneDetector.TimeZone('-03:00','America/Argentina/Buenos_Aires', false),
- '-180,1,s' : new jzTimezoneDetector.TimeZone('-03:00','America/Montevideo', true),
- '-120,0' : new jzTimezoneDetector.TimeZone('-02:00','America/Noronha', false),
- '-120,1' : new jzTimezoneDetector.TimeZone('-02:00','Etc/GMT+2', true),
- '-60,1' : new jzTimezoneDetector.TimeZone('-01:00','Atlantic/Azores', true),
- '-60,0' : new jzTimezoneDetector.TimeZone('-01:00','Atlantic/Cape_Verde', false),
- '0,0' : new jzTimezoneDetector.TimeZone('00:00','Etc/UTC', false),
- '0,1' : new jzTimezoneDetector.TimeZone('00:00','Europe/London', true),
- '60,1' : new jzTimezoneDetector.TimeZone('+01:00','Europe/Berlin', true),
- '60,0' : new jzTimezoneDetector.TimeZone('+01:00','Africa/Lagos', false),
- '60,1,s' : new jzTimezoneDetector.TimeZone('+01:00','Africa/Windhoek',true),
- '120,1' : new jzTimezoneDetector.TimeZone('+02:00','Asia/Beirut', true),
- '120,0' : new jzTimezoneDetector.TimeZone('+02:00','Africa/Johannesburg', false),
- '180,1' : new jzTimezoneDetector.TimeZone('+03:00','Europe/Moscow', true),
- '180,0' : new jzTimezoneDetector.TimeZone('+03:00','Asia/Baghdad', false),
- '210,1' : new jzTimezoneDetector.TimeZone('+03:30','Asia/Tehran', true),
- '240,0' : new jzTimezoneDetector.TimeZone('+04:00','Asia/Dubai', false),
- '240,1' : new jzTimezoneDetector.TimeZone('+04:00','Asia/Yerevan', true),
- '270,0' : new jzTimezoneDetector.TimeZone('+04:30','Asia/Kabul', false),
- '300,1' : new jzTimezoneDetector.TimeZone('+05:00','Asia/Yekaterinburg', true),
- '300,0' : new jzTimezoneDetector.TimeZone('+05:00','Asia/Karachi', false),
- '330,0' : new jzTimezoneDetector.TimeZone('+05:30','Asia/Kolkata', false),
- '345,0' : new jzTimezoneDetector.TimeZone('+05:45','Asia/Kathmandu', false),
- '360,0' : new jzTimezoneDetector.TimeZone('+06:00','Asia/Dhaka', false),
- '360,1' : new jzTimezoneDetector.TimeZone('+06:00','Asia/Omsk', true),
- '390,0' : new jzTimezoneDetector.TimeZone('+06:30','Asia/Rangoon', false),
- '420,1' : new jzTimezoneDetector.TimeZone('+07:00','Asia/Krasnoyarsk', true),
- '420,0' : new jzTimezoneDetector.TimeZone('+07:00','Asia/Jakarta', false),
- '480,0' : new jzTimezoneDetector.TimeZone('+08:00','Asia/Shanghai', false),
- '480,1' : new jzTimezoneDetector.TimeZone('+08:00','Asia/Irkutsk', true),
- '525,0' : new jzTimezoneDetector.TimeZone('+08:45','Australia/Eucla', true),
- '525,1,s' : new jzTimezoneDetector.TimeZone('+08:45','Australia/Eucla', true),
- '540,1' : new jzTimezoneDetector.TimeZone('+09:00','Asia/Yakutsk', true),
- '540,0' : new jzTimezoneDetector.TimeZone('+09:00','Asia/Tokyo', false),
- '570,0' : new jzTimezoneDetector.TimeZone('+09:30','Australia/Darwin', false),
- '570,1,s' : new jzTimezoneDetector.TimeZone('+09:30','Australia/Adelaide', true),
- '600,0' : new jzTimezoneDetector.TimeZone('+10:00','Australia/Brisbane', false),
- '600,1' : new jzTimezoneDetector.TimeZone('+10:00','Asia/Vladivostok', true),
- '600,1,s' : new jzTimezoneDetector.TimeZone('+10:00','Australia/Sydney', true),
- '630,1,s' : new jzTimezoneDetector.TimeZone('+10:30','Australia/Lord_Howe', true),
- '660,1' : new jzTimezoneDetector.TimeZone('+11:00','Asia/Kamchatka', true),
- '660,0' : new jzTimezoneDetector.TimeZone('+11:00','Pacific/Noumea', false),
- '690,0' : new jzTimezoneDetector.TimeZone('+11:30','Pacific/Norfolk', false),
- '720,1,s' : new jzTimezoneDetector.TimeZone('+12:00','Pacific/Auckland', true),
- '720,0' : new jzTimezoneDetector.TimeZone('+12:00','Pacific/Tarawa', false),
- '765,1,s' : new jzTimezoneDetector.TimeZone('+12:45','Pacific/Chatham', true),
- '780,0' : new jzTimezoneDetector.TimeZone('+13:00','Pacific/Tongatapu', false),
- '840,0' : new jzTimezoneDetector.TimeZone('+14:00','Pacific/Kiritimati', false)
- };
-
- /**
- * This object contains information on when daylight savings starts for
- * different timezones.
- *
- * The list is short for a reason. Often we do not have to be very specific
- * to single out the correct timezone. But when we do, this list comes in
- * handy.
- *
- * Each value is a date denoting when daylight savings starts for that timezone.
- */
- jzTimezoneDetector.olson.dst_start_dates = {
- 'America/Denver' : new Date(2011, 2, 13, 3, 0, 0, 0),
- 'America/Mazatlan' : new Date(2011, 3, 3, 3, 0, 0, 0),
- 'America/Chicago' : new Date(2011, 2, 13, 3, 0, 0, 0),
- 'America/Mexico_City' : new Date(2011, 3, 3, 3, 0, 0, 0),
- 'Atlantic/Stanley' : new Date(2011, 8, 4, 7, 0, 0, 0),
- 'America/Asuncion' : new Date(2011, 9, 2, 3, 0, 0, 0),
- 'America/Santiago' : new Date(2011, 9, 9, 3, 0, 0, 0),
- 'America/Campo_Grande' : new Date(2011, 9, 16, 5, 0, 0, 0),
- 'America/Montevideo' : new Date(2011, 9, 2, 3, 0, 0, 0),
- 'America/Sao_Paulo' : new Date(2011, 9, 16, 5, 0, 0, 0),
- 'America/Los_Angeles' : new Date(2011, 2, 13, 8, 0, 0, 0),
- 'America/Santa_Isabel' : new Date(2011, 3, 5, 8, 0, 0, 0),
- 'America/Havana' : new Date(2011, 2, 13, 2, 0, 0, 0),
- 'America/New_York' : new Date(2011, 2, 13, 7, 0, 0, 0),
- 'Asia/Gaza' : new Date(2011, 2, 26, 23, 0, 0, 0),
- 'Asia/Beirut' : new Date(2011, 2, 27, 1, 0, 0, 0),
- 'Europe/Minsk' : new Date(2011, 2, 27, 3, 0, 0, 0),
- 'Europe/Istanbul' : new Date(2011, 2, 27, 7, 0, 0, 0),
- 'Asia/Damascus' : new Date(2011, 3, 1, 2, 0, 0, 0),
- 'Asia/Jerusalem' : new Date(2011, 3, 1, 6, 0, 0, 0),
- 'Africa/Cairo' : new Date(2011, 3, 29, 4, 0, 0, 0),
- 'Asia/Yerevan' : new Date(2011, 2, 27, 4, 0, 0, 0),
- 'Asia/Baku' : new Date(2011, 2, 27, 8, 0, 0, 0),
- 'Pacific/Auckland' : new Date(2011, 8, 26, 7, 0, 0, 0),
- 'Pacific/Fiji' : new Date(2010, 11, 29, 23, 0, 0, 0),
- 'America/Halifax' : new Date(2011, 2, 13, 6, 0, 0, 0),
- 'America/Goose_Bay' : new Date(2011, 2, 13, 2, 1, 0, 0),
- 'America/Miquelon' : new Date(2011, 2, 13, 5, 0, 0, 0),
- 'America/Godthab' : new Date(2011, 2, 27, 1, 0, 0, 0)
- };
-
- /**
- * The keys in this object are timezones that we know may be ambiguous after
- * a preliminary scan through the olson_tz object.
- *
- * The array of timezones to compare must be in the order that daylight savings
- * starts for the regions.
- */
- jzTimezoneDetector.olson.ambiguity_list = {
- 'America/Denver' : ['America/Denver','America/Mazatlan'],
- 'America/Chicago' : ['America/Chicago','America/Mexico_City'],
- 'America/Asuncion' : ['Atlantic/Stanley', 'America/Asuncion', 'America/Santiago','America/Campo_Grande'],
- 'America/Montevideo' : ['America/Montevideo', 'America/Sao_Paulo'],
- 'Asia/Beirut' : ['Asia/Gaza','Asia/Beirut', 'Europe/Minsk', 'Europe/Istanbul', 'Asia/Damascus', 'Asia/Jerusalem','Africa/Cairo'],
- 'Asia/Yerevan' : ['Asia/Yerevan', 'Asia/Baku'],
- 'Pacific/Auckland' : ['Pacific/Auckland', 'Pacific/Fiji'],
- 'America/Los_Angeles' : ['America/Los_Angeles', 'America/Santa_Isabel'],
- 'America/New_York' : ['America/Havana','America/New_York'],
- 'America/Halifax' : ['America/Goose_Bay','America/Halifax'],
- 'America/Godthab' : ['America/Miquelon', 'America/Godthab']
- };
- /*
- mustache.js — Logic-less templates in JavaScript
- See http://mustache.github.com/ for more info.
- */
- var Mustache = function() {
- var Renderer = function() {};
- Renderer.prototype = {
- otag: "{{",
- ctag: "}}",
- pragmas: {},
- buffer: [],
- pragmas_implemented: {
- "IMPLICIT-ITERATOR": true
- },
- context: {},
- render: function(template, context, partials, in_recursion) {
- // reset buffer & set context
- if(!in_recursion) {
- this.context = context;
- this.buffer = []; // TODO: make this non-lazy
- }
- // fail fast
- if(!this.includes("", template)) {
- if(in_recursion) {
- return template;
- } else {
- this.send(template);
- return;
- }
- }
- template = this.render_pragmas(template);
- var html = this.render_section(template, context, partials);
- if(in_recursion) {
- return this.render_tags(html, context, partials, in_recursion);
- }
- this.render_tags(html, context, partials, in_recursion);
- },
- /*
- Sends parsed lines
- */
- send: function(line) {
- if(line != "") {
- this.buffer.push(line);
- }
- },
- /*
- Looks for %PRAGMAS
- */
- render_pragmas: function(template) {
- // no pragmas
- if(!this.includes("%", template)) {
- return template;
- }
- var that = this;
- var regex = new RegExp(this.otag + "%([\\w-]+) ?([\\w]+=[\\w]+)?" +
- this.ctag);
- return template.replace(regex, function(match, pragma, options) {
- if(!that.pragmas_implemented[pragma]) {
- throw({message:
- "This implementation of mustache doesn't understand the '" +
- pragma + "' pragma"});
- }
- that.pragmas[pragma] = {};
- if(options) {
- var opts = options.split("=");
- that.pragmas[pragma][opts[0]] = opts[1];
- }
- return "";
- // ignore unknown pragmas silently
- });
- },
- /*
- Tries to find a partial in the curent scope and render it
- */
- render_partial: function(name, context, partials) {
- name = this.trim(name);
- if(!partials || partials[name] === undefined) {
- throw({message: "unknown_partial '" + name + "'"});
- }
- if(typeof(context[name]) != "object") {
- return this.render(partials[name], context, partials, true);
- }
- return this.render(partials[name], context[name], partials, true);
- },
- /*
- Renders inverted (^) and normal (#) sections
- */
- render_section: function(template, context, partials) {
- if(!this.includes("#", template) && !this.includes("^", template)) {
- return template;
- }
- var that = this;
- // CSW - Added "+?" so it finds the tighest bound, not the widest
- var regex = new RegExp(this.otag + "(\\^|\\#)\\s*(.+)\\s*" + this.ctag +
- "\n*([\\s\\S]+?)" + this.otag + "\\/\\s*\\2\\s*" + this.ctag +
- "\\s*", "mg");
- // for each {{#foo}}{{/foo}} section do...
- return template.replace(regex, function(match, type, name, content) {
- var value = that.find(name, context);
- if(type == "^") { // inverted section
- if(!value || that.is_array(value) && value.length === 0) {
- // false or empty list, render it
- return that.render(content, context, partials, true);
- } else {
- return "";
- }
- } else if(type == "#") { // normal section
- if(that.is_array(value)) { // Enumerable, Let's loop!
- return that.map(value, function(row) {
- return that.render(content, that.create_context(row),
- partials, true);
- }).join("");
- } else if(that.is_object(value)) { // Object, Use it as subcontext!
- return that.render(content, that.create_context(value),
- partials, true);
- } else if(typeof value === "function") {
- // higher order section
- return value.call(context, content, function(text) {
- return that.render(text, context, partials, true);
- });
- } else if(value) { // boolean section
- return that.render(content, context, partials, true);
- } else {
- return "";
- }
- }
- });
- },
- /*
- Replace {{foo}} and friends with values from our view
- */
- render_tags: function(template, context, partials, in_recursion) {
- // tit for tat
- var that = this;
- var new_regex = function() {
- return new RegExp(that.otag + "(=|!|>|\\{|%)?([^\\/#\\^]+?)\\1?" +
- that.ctag + "+", "g");
- };
- var regex = new_regex();
- var tag_replace_callback = function(match, operator, name) {
- switch(operator) {
- case "!": // ignore comments
- return "";
- case "=": // set new delimiters, rebuild the replace regexp
- that.set_delimiters(name);
- regex = new_regex();
- return "";
- case ">": // render partial
- return that.render_partial(name, context, partials);
- case "{": // the triple mustache is unescaped
- return that.find(name, context);
- default: // escape the value
- return that.escape(that.find(name, context));
- }
- };
- var lines = template.split("\n");
- for(var i = 0; i < lines.length; i++) {
- lines[i] = lines[i].replace(regex, tag_replace_callback, this);
- if(!in_recursion) {
- this.send(lines[i]);
- }
- }
- if(in_recursion) {
- return lines.join("\n");
- }
- },
- set_delimiters: function(delimiters) {
- var dels = delimiters.split(" ");
- this.otag = this.escape_regex(dels[0]);
- this.ctag = this.escape_regex(dels[1]);
- },
- escape_regex: function(text) {
- // thank you Simon Willison
- if(!arguments.callee.sRE) {
- var specials = [
- '/', '.', '*', '+', '?', '|',
- '(', ')', '[', ']', '{', '}', '\\'
- ];
- arguments.callee.sRE = new RegExp(
- '(\\' + specials.join('|\\') + ')', 'g'
- );
- }
- return text.replace(arguments.callee.sRE, '\\$1');
- },
- /*
- find `name` in current `context`. That is find me a value
- from the view object
- */
- find: function(name, context) {
- name = this.trim(name);
- // Checks whether a value is thruthy or false or 0
- function is_kinda_truthy(bool) {
- return bool === false || bool === 0 || bool;
- }
- var value = context;
- var path = name.split(/\./);
- for(var i = 0; i < path.length; i++) {
- name = path[i];
- if(value && is_kinda_truthy(value[name])) {
- value = value[name];
- } else if(i == 0 && is_kinda_truthy(this.context[name])) {
- value = this.context[name];
- } else {
- value = undefined;
- }
- }
- if(typeof value === "function") {
- return value.apply(context);
- }
- if(value !== undefined) {
- return value;
- }
- // silently ignore unkown variables
- return "";
- },
- // Utility methods
- /* includes tag */
- includes: function(needle, haystack) {
- return haystack.indexOf(this.otag + needle) != -1;
- },
- /*
- Does away with nasty characters
- */
- escape: function(s) {
- s = String(s === null ? "" : s);
- return s.replace(/&(?!\w+;)|["'<>\\]/g, function(s) {
- switch(s) {
- case "&": return "&";
- case "\\": return "\\\\";
- case '"': return '"';
- case "'": return ''';
- case "<": return "<";
- case ">": return ">";
- default: return s;
- }
- });
- },
- // by @langalex, support for arrays of strings
- create_context: function(_context) {
- if(this.is_object(_context)) {
- return _context;
- } else {
- var iterator = ".";
- if(this.pragmas["IMPLICIT-ITERATOR"]) {
- iterator = this.pragmas["IMPLICIT-ITERATOR"].iterator;
- }
- var ctx = {};
- ctx[iterator] = _context;
- return ctx;
- }
- },
- is_object: function(a) {
- return a && typeof a == "object";
- },
- is_array: function(a) {
- return Object.prototype.toString.call(a) === '[object Array]';
- },
- /*
- Gets rid of leading and trailing whitespace
- */
- trim: function(s) {
- return s.replace(/^\s*|\s*$/g, "");
- },
- /*
- Why, why, why? Because IE. Cry, cry cry.
- */
- map: function(array, fn) {
- if (typeof array.map == "function") {
- return array.map(fn);
- } else {
- var r = [];
- var l = array.length;
- for(var i = 0; i < l; i++) {
- r.push(fn(array[i]));
- }
- return r;
- }
- }
- };
- return({
- name: "mustache.js",
- version: "0.3.1-dev",
- /*
- Turns a template and view into HTML
- */
- to_html: function(template, view, partials, send_fun) {
- var renderer = new Renderer();
- if(send_fun) {
- renderer.send = send_fun;
- }
- renderer.render(template, view, partials);
- if(!send_fun) {
- return renderer.buffer.join("\n");
- }
- }
- });
- }();
- /*
- * More info at: http://phpjs.org
- *
- * This is version: 3.24
- * php.js is copyright 2011 Kevin van Zonneveld.
- *
- * Portions copyright Brett Zamir (http://brett-zamir.me), Kevin van Zonneveld
- * (http://kevin.vanzonneveld.net), Onno Marsman, Theriault, Michael White
- * (http://getsprink.com), Waldo Malqui Silva, Paulo Freitas, Jonas Raoni
- * Soares Silva (http://www.jsfromhell.com), Jack, Philip Peterson, Ates Goral
- * (http://magnetiq.com), Legaev Andrey, Ratheous, Alex, Martijn Wieringa,
- * Nate, lmeyrick (https://sourceforge.net/projects/bcmath-js/), Enrique
- * Gonzalez, Philippe Baumann, Rafał Kukawski (http://blog.kukawski.pl),
- * Webtoolkit.info (http://www.webtoolkit.info/), Ole Vrijenhoek, Ash Searle
- * (http://hexmen.com/blog/), travc, Carlos R. L. Rodrigues
- * (http://www.jsfromhell.com), Jani Hartikainen, stag019, GeekFG
- * (http://geekfg.blogspot.com), WebDevHobo (http://webdevhobo.blogspot.com/),
- * Erkekjetter, pilus, Rafał Kukawski (http://blog.kukawski.pl/), Johnny Mast
- * (http://www.phpvrouwen.nl), T.Wild,
- * http://stackoverflow.com/questions/57803/how-to-convert-decimal-to-hex-in-javascript,
- * d3x, Michael Grier, Andrea Giammarchi (http://webreflection.blogspot.com),
- * marrtins, Mailfaker (http://www.weedem.fr/), Steve Hilder, gettimeofday,
- * mdsjack (http://www.mdsjack.bo.it), felix, majak, Steven Levithan
- * (http://blog.stevenlevithan.com), Mirek Slugen, Oleg Eremeev, Felix
- * Geisendoerfer (http://www.debuggable.com/felix), Martin
- * (http://www.erlenwiese.de/), gorthaur, Lars Fischer, Joris, AJ, Paul Smith,
- * Tim de Koning (http://www.kingsquare.nl), KELAN, Josh Fraser
- * (http://onlineaspect.com/2007/06/08/auto-detect-a-time-zone-with-javascript/),
- * Chris, Marc Palau, Kevin van Zonneveld (http://kevin.vanzonneveld.net/),
- * Arpad Ray (mailto:arpad@php.net), Breaking Par Consulting Inc
- * (http://www.breakingpar.com/bkp/home.nsf/0/87256B280015193F87256CFB006C45F7),
- * Nathan, Karol Kowalski, David, Dreamer, Diplom@t (http://difane.com/), Caio
- * Ariede (http://caioariede.com), Robin, Imgen Tata (http://www.myipdf.com/),
- * Pellentesque Malesuada, saulius, Aman Gupta, Sakimori, Tyler Akins
- * (http://rumkin.com), Thunder.m, Public Domain
- * (http://www.json.org/json2.js), Michael White, Kankrelune
- * (http://www.webfaktory.info/), Alfonso Jimenez
- * (http://www.alfonsojimenez.com), Frank Forte, vlado houba, Marco, Billy,
- * David James, madipta, noname, sankai, class_exists, Jalal Berrami, ger,
- * Itsacon (http://www.itsacon.net/), Scott Cariss, nobbler, Arno, Denny
- * Wardhana, ReverseSyntax, Mateusz "loonquawl" Zalega, Slawomir Kaniecki,
- * Francois, Fox, mktime, Douglas Crockford (http://javascript.crockford.com),
- * john (http://www.jd-tech.net), Oskar Larsson Högfeldt
- * (http://oskar-lh.name/), marc andreu, Nick Kolosov (http://sammy.ru), date,
- * Marc Jansen, Steve Clay, Olivier Louvignes (http://mg-crea.com/), Soren
- * Hansen, merabi, Subhasis Deb, josh, T0bsn, Tim Wiel, Brad Touesnard, MeEtc
- * (http://yass.meetcweb.com), Peter-Paul Koch
- * (http://www.quirksmode.org/js/beat.html), Pyerre, Jon Hohle, duncan, Bayron
- * Guevara, Adam Wallner (http://web2.bitbaro.hu/), paulo kuong, Gilbert,
- * Lincoln Ramsay, Thiago Mata (http://thiagomata.blog.com), Linuxworld,
- * lmeyrick (https://sourceforge.net/projects/bcmath-js/this.), djmix, Bryan
- * Elliott, David Randall, Sanjoy Roy, jmweb, Francesco, Stoyan Kyosev
- * (http://www.svest.org/), J A R, kenneth, T. Wild, Ole Vrijenhoek
- * (http://www.nervous.nl/), Raphael (Ao RUDLER), Shingo, LH, JB, nord_ua, jd,
- * JT, Thomas Beaucourt (http://www.webapp.fr), Ozh, XoraX
- * (http://www.xorax.info), EdorFaus, Eugene Bulkin (http://doubleaw.com/),
- * Der Simon (http://innerdom.sourceforge.net/), 0m3r, echo is bad,
- * FremyCompany, stensi, Kristof Coomans (SCK-CEN Belgian Nucleair Research
- * Centre), Devan Penner-Woelk, Pierre-Luc Paour, Martin Pool, Brant Messenger
- * (http://www.brantmessenger.com/), Kirk Strobeck, Saulo Vallory, Christoph,
- * Wagner B. Soares, Artur Tchernychev, Valentina De Rosa, Jason Wong
- * (http://carrot.org/), Daniel Esteban, strftime, Rick Waldron, Mick@el,
- * Anton Ongson, Bjorn Roesbeke (http://www.bjornroesbeke.be/), Simon Willison
- * (http://simonwillison.net), Gabriel Paderni, Philipp Lenssen, Marco van
- * Oort, Bug?, Blues (http://tech.bluesmoon.info/), Tomasz Wesolowski, rezna,
- * Eric Nagel, Evertjan Garretsen, Luke Godfrey, Pul, Bobby Drake, uestla,
- * Alan C, Ulrich, Zahlii, Yves Sucaet, sowberry, Norman "zEh" Fuchs, hitwork,
- * johnrembo, Brian Tafoya (http://www.premasolutions.com/), Nick Callen,
- * Steven Levithan (stevenlevithan.com), ejsanders, Scott Baker, Philippe
- * Jausions (http://pear.php.net/user/jausions), Aidan Lister
- * (http://aidanlister.com/), Rob, e-mike, HKM, ChaosNo1, metjay, strcasecmp,
- * strcmp, Taras Bogach, jpfle, Alexander Ermolaev
- * (http://snippets.dzone.com/user/AlexanderErmolaev), DxGx, kilops, Orlando,
- * dptr1988, Le Torbi, James (http://www.james-bell.co.uk/), Pedro Tainha
- * (http://www.pedrotainha.com), James, penutbutterjelly, Arnout Kazemier
- * (http://www.3rd-Eden.com), 3D-GRAF, daniel airton wermann
- * (http://wermann.com.br), jakes, Yannoo, FGFEmperor, gabriel paderni, Atli
- * Þór, Maximusya, Diogo Resende, Rival, Howard Yeend, Allan Jensen
- * (http://www.winternet.no), davook, Benjamin Lupton, baris ozdil, Greg
- * Frazier, Manish, Matt Bradley, Cord, fearphage
- * (http://http/my.opera.com/fearphage/), Matteo, Victor, taith, Tim de
- * Koning, Ryan W Tenney (http://ryan.10e.us), Tod Gentille, Alexander M
- * Beedie, Riddler (http://www.frontierwebdev.com/), Luis Salazar
- * (http://www.freaky-media.com/), Rafał Kukawski, T.J. Leahy, Luke Smith
- * (http://lucassmith.name), Kheang Hok Chin (http://www.distantia.ca/),
- * Russell Walker (http://www.nbill.co.uk/), Jamie Beck
- * (http://www.terabit.ca/), Garagoth, Andrej Pavlovic, Dino, Le Torbi
- * (http://www.letorbi.de/), Ben (http://benblume.co.uk/), DtTvB
- * (http://dt.in.th/2008-09-16.string-length-in-bytes.html), Michael, Chris
- * McMacken, setcookie, YUI Library:
- * http://developer.yahoo.com/yui/docs/YAHOO.util.DateLocale.html, Andreas,
- * Blues at http://hacks.bluesmoon.info/strftime/strftime.js, rem, Josep Sanz
- * (http://www.ws3.es/), Cagri Ekin, Lorenzo Pisani, incidence, Amirouche, Jay
- * Klehr, Amir Habibi (http://www.residence-mixte.com/), Tony, booeyOH, meo,
- * William, Greenseed, Yen-Wei Liu, Ben Bryan, Leslie Hoare, mk.keck
- *
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL KEVIN VAN ZONNEVELD BE LIABLE FOR ANY CLAIM, DAMAGES
- * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
- // jslint.com configuration options. See: http://wiki.github.com/kvz/phpjs/jslint-options
- /* global window */
- /* jslint adsafe: false, bitwise: false, browser: false, cap: false, css: false, debug: false, devel: false, eqeqeq: true, evil: false, forin: false, fragment: false, immed: true, indent: 4, laxbreak: false, maxerr: 100, maxlen: 80, newcap: true, nomen: false, on: true, onevar: false, passfail: false, plusplus: false, regexp: false, rhino: false, safe: false, sidebar: false, strict: false, sub: false, undef: true, white: false, widget: false */
-
- // Our idea with CommonJS is that you can do the following:
- // var php = require('php');
- // php.md5('test');
- var php = {};
-
- php.ini_set = function (varname, newvalue) {
- // http://kevin.vanzonneveld.net
- // + original by: Brett Zamir (http://brett-zamir.me)
- // % note 1: This will not set a global_value or access level for the ini item
- // * example 1: ini_set('date.timezone', 'America/Chicago');
- // * returns 1: 'Asia/Hong_Kong'
-
- var oldval = '',
- that = this;
- this.php_js = this.php_js || {};
- this.php_js.ini = this.php_js.ini || {};
- this.php_js.ini[varname] = this.php_js.ini[varname] || {};
- oldval = this.php_js.ini[varname].local_value;
-
- var _setArr = function (oldval) { // Although these are set individually, they are all accumulated
- if (typeof oldval === 'undefined') {
- that.php_js.ini[varname].local_value = [];
- }
- that.php_js.ini[varname].local_value.push(newvalue);
- };
-
- switch (varname) {
- case 'extension':
- if (typeof this.dl === 'function') {
- this.dl(newvalue); // This function is only experimental in php.js
- }
- _setArr(oldval, newvalue);
- break;
- default:
- this.php_js.ini[varname].local_value = newvalue;
- break;
- }
- return oldval;
- };
- php.ini_get = function (varname) {
- // http://kevin.vanzonneveld.net
- // + original by: Brett Zamir (http://brett-zamir.me)
- // % note 1: The ini values must be set by ini_set or manually within an ini file
- // * example 1: ini_get('date.timezone');
- // * returns 1: 'Asia/Hong_Kong'
- if (this.php_js && this.php_js.ini && this.php_js.ini[varname] && this.php_js.ini[varname].local_value !== undefined) {
- if (this.php_js.ini[varname].local_value === null) {
- return '';
- }
- return this.php_js.ini[varname].local_value;
- }
- return '';
- }
-
- php.ctype_digit = function (text) {
- // http://kevin.vanzonneveld.net
- // + original by: Brett Zamir (http://brett-zamir.me)
- // - depends on: setlocale
- // * example 1: ctype_digit('150');
- // * returns 1: true
- if (typeof text !== 'string') {
- return false;
- }
- // BEGIN REDUNDANT
- this.setlocale('LC_ALL', 0); // ensure setup of localization variables takes place
- // END REDUNDANT
- return text.search(this.php_js.locales[this.php_js.localeCategories.LC_CTYPE].LC_CTYPE.dg) !== -1;
- };
- php.gmmktime = function () {
- // http://kevin.vanzonneveld.net
- // + original by: Brett Zamir (http://brett-zamir.me)
- // + derived from: mktime
- // * example 1: gmmktime(14, 10, 2, 2, 1, 2008);
- // * returns 1: 1201875002
- // * example 2: gmmktime(0, 0, -1, 1, 1, 1970);
- // * returns 2: -1
- var d = new Date(),
- r = arguments,
- i = 0,
- e = ['Hours', 'Minutes', 'Seconds', 'Month', 'Date', 'FullYear'];
-
- for (i = 0; i < e.length; i++) {
- if (typeof r[i] === 'undefined') {
- r[i] = d['getUTC' + e[i]]();
- r[i] += (i === 3); // +1 to fix JS months.
- } else {
- r[i] = parseInt(r[i], 10);
- if (isNaN(r[i])) {
- return false;
- }
- }
- }
-
- // Map years 0-69 to 2000-2069 and years 70-100 to 1970-2000.
- r[5] += (r[5] >= 0 ? (r[5] <= 69 ? 2e3 : (r[5] <= 100 ? 1900 : 0)) : 0);
-
- // Set year, month (-1 to fix JS months), and date.
- // !This must come before the call to setHours!
- d.setUTCFullYear(r[5], r[3] - 1, r[4]);
-
- // Set hours, minutes, and seconds.
- d.setUTCHours(r[0], r[1], r[2]);
-
- // Divide milliseconds by 1000 to return seconds and drop decimal.
- // Add 1 second if negative or it'll be off from PHP by 1 second.
- return (d.getTime() / 1e3 >> 0) - (d.getTime() < 0);
- };
- php.getdate = function (timestamp) {
- // http://kevin.vanzonneveld.net
- // + original by: Paulo Freitas
- // + input by: Alex
- // + bugfixed by: Brett Zamir (http://brett-zamir.me)
- // * example 1: getdate(1055901520);
- // * returns 1: {'seconds': 40, 'minutes': 58, 'hours': 21, 'mday': 17, 'wday': 2, 'mon': 6, 'year': 2003, 'yday': 167, 'weekday': 'Tuesday', 'month': 'June', '0': 1055901520}
- var _w = ['Sun', 'Mon', 'Tues', 'Wednes', 'Thurs', 'Fri', 'Satur'];
- var _m = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
- var d = ((typeof(timestamp) == 'undefined') ? new Date() : // Not provided
- (typeof(timestamp) == 'object') ? new Date(timestamp) : // Javascript Date()
- new Date(timestamp * 1000) // UNIX timestamp (auto-convert to int)
- );
- var w = d.getDay();
- var m = d.getMonth();
- var y = d.getFullYear();
- var r = {};
-
- r.seconds = d.getSeconds();
- r.minutes = d.getMinutes();
- r.hours = d.getHours();
- r.mday = d.getDate();
- r.wday = w;
- r.mon = m + 1;
- r.year = y;
- r.yday = Math.floor((d - (new Date(y, 0, 1))) / 86400000);
- r.weekday = _w[w] + 'day';
- r.month = _m[m];
- r['0'] = parseInt(d.getTime() / 1000, 10);
-
- return r;
- };
- php.checkdate = function (m, d, y) {
- // Returns true(1) if it is a valid date in gregorian calendar
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/checkdate
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Pyerre
- // + improved by: Theriault
- // * example 1: checkdate(12, 31, 2000);
- // * returns 1: true
- // * example 2: checkdate(2, 29, 2001);
- // * returns 2: false
- // * example 3: checkdate(3, 31, 2008);
- // * returns 3: true
- // * example 4: checkdate(1, 390, 2000);
- // * returns 4: false
- return m > 0 && m < 13 && y > 0 && y < 32768 && d > 0 && d <= (new Date(y, m, 0)).getDate();
- };
- php.gmdate = function (format, timestamp) {
- // Format a GMT date/time
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/gmdate
- // + original by: Brett Zamir (http://brett-zamir.me)
- // + input by: Alex
- // + bugfixed by: Brett Zamir (http://brett-zamir.me)
- // - depends on: date
- // * example 1: gmdate('H:m:s \\m \\i\\s \\m\\o\\n\\t\\h', 1062402400); // Return will depend on your timezone
- // * returns 1: '07:09:40 m is month'
- var dt = ((typeof(timestamp) == 'undefined') ? new Date() : // Not provided
- (typeof(timestamp) == 'object') ? new Date(timestamp) : // Javascript Date()
- new Date(timestamp * 1000) // UNIX timestamp (auto-convert to int)
- );
- timestamp = Date.parse(dt.toUTCString().slice(0, -4)) / 1000;
- return this.date(format, timestamp);
- };
- php.mt_rand = function (min, max) {
- // Returns a random number from Mersenne Twister
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/mt_rand
- // + original by: Onno Marsman
- // * example 1: mt_rand(1, 1);
- // * returns 1: 1
- var argc = arguments.length;
- if (argc === 0) {
- min = 0;
- max = 2147483647;
- } else if (argc === 1) {
- throw new Error('Warning: mt_rand() expects exactly 2 parameters, 1 given');
- }
- return Math.floor(Math.random() * (max - min + 1)) + min;
- };
-
- php.abs = function (mixed_number) {
- // Return the absolute value of the number
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/abs
- // + original by: Waldo Malqui Silva
- // + improved by: Karol Kowalski
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
- // * example 1: \php.abs(4.2);
- // * returns 1: 4.2
- // * example 2: \php.abs(-4.2);
- // * returns 2: 4.2
- // * example 3: \php.abs(-5);
- // * returns 3: 5
- // * example 4: \php.abs('_argos');
- // * returns 4: 0
- return Math.abs(mixed_number) || 0;
- };
-
- php.addcslashes = function (str, charlist) {
- // Escapes all chars mentioned in charlist with backslash. It creates octal representations if asked to backslash characters with 8th bit set or with ASCII<32 (except '\n', '\r', '\t' etc...)
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/addcslashes
- // + original by: Brett Zamir (http://brett-zamir.me)
- // % note 1: We show double backslashes in the return value example code below because a JavaScript string will not
- // % note 1: render them as backslashes otherwise
- // * example 1: \php.addcslashes('foo[ ]', 'A..z'); // Escape all ASCII within capital A to lower z range, including square brackets
- // * returns 1: "\\f\\o\\o\\[ \\]"
- // * example 2: \php.addcslashes("zoo['.']", 'z..A'); // Only escape z, period, and A here since not a lower-to-higher range
- // * returns 2: "\\zoo['\\.']"
- // * example 3: \php.addcslashes("@a\u0000\u0010\u00A9", "\0..\37!@\177..\377") == '\\@a\\000\\020\\302\\251'); // Escape as octals those specified and less than 32 (0x20) or greater than 126 (0x7E), but not otherwise
- // * returns 3: true
- // * example 4: \php.addcslashes("\u0020\u007E", "\40..\175") == '\\ ~'); // Those between 32 (0x20 or 040) and 126 (0x7E or 0176) decimal value will be backslashed if specified (not octalized)
- // * returns 4: true
- // * example 5: \php.addcslashes("\r\u0007\n", '\0..\37'); // Recognize C escape sequences if specified
- // * returns 5: "\\r\\a\\n"
- // * example 6: \php.addcslashes("\r\u0007\n", '\0'); // Do not recognize C escape sequences if not specified
- // * returns 7: "\r\u0007\n"
- var target = '',
- chrs = [],
- i = 0,
- j = 0,
- c = '',
- next = '',
- rangeBegin = '',
- rangeEnd = '',
- chr = '',
- begin = 0,
- end = 0,
- octalLength = 0,
- postOctalPos = 0,
- cca = 0,
- escHexGrp = [],
- encoded = '',
- percentHex = /%([\dA-Fa-f]+)/g;
- var _pad = function (n, c) {
- if ((n = n + "").length < c) {
- return new Array(++c - n.length).join("0") + n;
- } else {
- return n;
- }
- };
-
- for (i = 0; i < charlist.length; i++) {
- c = charlist.charAt(i);
- next = charlist.charAt(i + 1);
- if (c === '\\' && next && (/\d/).test(next)) { // Octal
- rangeBegin = charlist.slice(i + 1).match(/^\d+/)[0];
- octalLength = rangeBegin.length;
- postOctalPos = i + octalLength + 1;
- if (charlist.charAt(postOctalPos) + charlist.charAt(postOctalPos + 1) === '..') { // Octal begins range
- begin = rangeBegin.charCodeAt(0);
- if ((/\\\d/).test(charlist.charAt(postOctalPos + 2) + charlist.charAt(postOctalPos + 3))) { // Range ends with octal
- rangeEnd = charlist.slice(postOctalPos + 3).match(/^\d+/)[0];
- i += 1; // Skip range end backslash
- } else if (charlist.charAt(postOctalPos + 2)) { // Range ends with character
- rangeEnd = charlist.charAt(postOctalPos + 2);
- } else {
- throw 'Range with no end point';
- }
- end = rangeEnd.charCodeAt(0);
- if (end > begin) { // Treat as a range
- for (j = begin; j <= end; j++) {
- chrs.push(String.fromCharCode(j));
- }
- } else { // Supposed to treat period, begin and end as individual characters only, not a range
- chrs.push('.', rangeBegin, rangeEnd);
- }
- i += rangeEnd.length + 2; // Skip dots and range end (already skipped range end backslash if present)
- } else { // Octal is by itself
- chr = String.fromCharCode(parseInt(rangeBegin, 8));
- chrs.push(chr);
- }
- i += octalLength; // Skip range begin
- } else if (next + charlist.charAt(i + 2) === '..') { // Character begins range
- rangeBegin = c;
- begin = rangeBegin.charCodeAt(0);
- if ((/\\\d/).test(charlist.charAt(i + 3) + charlist.charAt(i + 4))) { // Range ends with octal
- rangeEnd = charlist.slice(i + 4).match(/^\d+/)[0];
- i += 1; // Skip range end backslash
- } else if (charlist.charAt(i + 3)) { // Range ends with character
- rangeEnd = charlist.charAt(i + 3);
- } else {
- throw 'Range with no end point';
- }
- end = rangeEnd.charCodeAt(0);
- if (end > begin) { // Treat as a range
- for (j = begin; j <= end; j++) {
- chrs.push(String.fromCharCode(j));
- }
- } else { // Supposed to treat period, begin and end as individual characters only, not a range
- chrs.push('.', rangeBegin, rangeEnd);
- }
- i += rangeEnd.length + 2; // Skip dots and range end (already skipped range end backslash if present)
- } else { // Character is by itself
- chrs.push(c);
- }
- }
-
- for (i = 0; i < str.length; i++) {
- c = str.charAt(i);
- if (chrs.indexOf(c) !== -1) {
- target += '\\';
- cca = c.charCodeAt(0);
- if (cca < 32 || cca > 126) { // Needs special escaping
- switch (c) {
- case '\n':
- target += 'n';
- break;
- case '\t':
- target += 't';
- break;
- case '\u000D':
- target += 'r';
- break;
- case '\u0007':
- target += 'a';
- break;
- case '\v':
- target += 'v';
- break;
- case '\b':
- target += 'b';
- break;
- case '\f':
- target += 'f';
- break;
- default:
- //target += _pad(cca.toString(8), 3);break; // Sufficient for UTF-16
- encoded = encodeURIComponent(c);
-
- // 3-length-padded UTF-8 octets
- if ((escHexGrp = percentHex.exec(encoded)) !== null) {
- target += _pad(parseInt(escHexGrp[1], 16).toString(8), 3); // already added a slash above
- }
- while ((escHexGrp = percentHex.exec(encoded)) !== null) {
- target += '\\' + _pad(parseInt(escHexGrp[1], 16).toString(8), 3);
- }
- break;
- }
- } else { // Perform regular backslashed escaping
- target += c;
- }
- } else { // Just add the character unescaped
- target += c;
- }
- }
- return target;
- };
-
- php.addslashes = function (str) {
- // Escapes single quote, double quotes and backslash characters in a string with backslashes
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/addslashes
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Ates Goral (http://magnetiq.com)
- // + improved by: marrtins
- // + improved by: Nate
- // + improved by: Onno Marsman
- // + input by: Denny Wardhana
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // + improved by: Oskar Larsson Högfeldt (http://oskar-lh.name/)
- // * example 1: \php.addslashes("kevin's birthday");
- // * returns 1: 'kevin\'s birthday'
- return (str + '').replace(/[\\"']/g, '\\$&').replace(/\u0000/g, '\\0');
- };
-
- php.array_chunk = function (input, size) {
- // Split array into chunks
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/array_chunk
- // + original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com)
- // * example 1: \php.array_chunk(['Kevin', 'van', 'Zonneveld'], 2);
- // * returns 1: {0 : {0: 'Kevin', 1: 'van'} , 1 : {0: 'Zonneveld'}}
- for (var x, i = 0, c = -1, l = input.length, n = []; i < l; i++) {
- (x = i % size) ? n[c][x] = input[i] : n[++c] = [input[i]];
- }
-
- return n;
- };
-
- php.array_combine = function (keys, values) {
- // Creates an array by using the elements of the first parameter as keys and the elements of the second as the corresponding values
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/array_combine
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // * example 1: \php.array_combine([0,1,2], ['kevin','van','zonneveld']);
- // * returns 1: {0: 'kevin', 1: 'van', 2: 'zonneveld'}
- var new_array = {},
- keycount = keys && keys.length,
- i = 0;
-
- // input sanitation
- if (typeof keys !== 'object' || typeof values !== 'object' || // Only accept arrays or array-like objects
- typeof keycount !== 'number' || typeof values.length !== 'number' || !keycount) { // Require arrays to have a count
- return false;
- }
-
- // number of elements does not match
- if (keycount != values.length) {
- return false;
- }
-
- for (i = 0; i < keycount; i++) {
- new_array[keys[i]] = values[i];
- }
-
- return new_array;
- };
-
- php.array_diff = function () {
- // Returns the entries of arr1 that have values which are not present in any of the others arguments.
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/array_diff
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Sanjoy Roy
- // + revised by: Brett Zamir (http://brett-zamir.me)
- // * example 1: \php.array_diff(['Kevin', 'van', 'Zonneveld'], ['van', 'Zonneveld']);
- // * returns 1: {0:'Kevin'}
- var arr1 = arguments[0],
- retArr = {};
- var k1 = '',
- i = 1,
- k = '',
- arr = {};
-
- arr1keys: for (k1 in arr1) {
- for (i = 1; i < arguments.length; i++) {
- arr = arguments[i];
- for (k in arr) {
- if (arr[k] === arr1[k1]) {
- // If it reaches here, it was found in at least one array, so try next value
- continue arr1keys;
- }
- }
- retArr[k1] = arr1[k1];
- }
- }
-
- return retArr;
- };
-
- php.array_fill = function (start_index, num, mixed_val) {
- // Create an array containing num elements starting with index start_key each initialized to val
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/array_fill
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Waldo Malqui Silva
- // * example 1: \php.array_fill(5, 6, 'banana');
- // * returns 1: { 5: 'banana', 6: 'banana', 7: 'banana', 8: 'banana', 9: 'banana', 10: 'banana' }
- var key, tmp_arr = {};
-
- if (!isNaN(start_index) && !isNaN(num)) {
- for (key = 0; key < num; key++) {
- tmp_arr[(key + start_index)] = mixed_val;
- }
- }
-
- return tmp_arr;
- };
-
- php.array_fill_keys = function (keys, value) {
- // Create an array using the elements of the first parameter as keys each initialized to val
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/array_fill_keys
- // + original by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: Brett Zamir (http://brett-zamir.me)
- // * example 1: \php.keys = {'a': 'foo', 2: 5, 3: 10, 4: 'bar'}
- // * example 1: \php.array_fill_keys(keys, 'banana')
- // * returns 1: {"foo": "banana", 5: "banana", 10: "banana", "bar": "banana"}
- var retObj = {},
- key = '';
-
- for (key in keys) {
- retObj[keys[key]] = value;
- }
-
- return retObj;
- };
-
- php.array_filter = function (arr, func) {
- // Filters elements from the array via the callback.
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/array_filter
- // + original by: Brett Zamir (http://brett-zamir.me)
- // % note 1: Takes a function as an argument, not a function's name
- // * example 1: \php.var odd = function (num) {return (num & 1);};
- // * example 1: \php.array_filter({"a": 1, "b": 2, "c": 3, "d": 4, "e": 5}, odd);
- // * returns 1: {"a": 1, "c": 3, "e": 5}
- // * example 2: \php.var even = function (num) {return (!(num & 1));}
- // * example 2: \php.array_filter([6, 7, 8, 9, 10, 11, 12], even);
- // * returns 2: {0: 6, 2: 8, 4: 10, 6: 12}
- var retObj = {},
- k;
-
- for (k in arr) {
- if (func(arr[k])) {
- retObj[k] = arr[k];
- }
- }
-
- return retObj;
- };
-
- php.array_flip = function (trans) {
- // Return array with key <-> value flipped
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/array_flip
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // * example 1: \php.array_flip( {a: 1, b: 1, c: 2} );
- // * returns 1: {1: 'b', 2: 'c'}
- var key, tmp_ar = {};
-
- for (key in trans) {
- tmp_ar[trans[key]] = key;
- }
-
- return tmp_ar;
- };
-
- php.array_intersect = function () {
- // Returns the entries of arr1 that have values which are present in all the other arguments
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/array_intersect
- // + original by: Brett Zamir (http://brett-zamir.me)
- // % note 1: These only output associative arrays (would need to be
- // % note 1: all numeric and counting from zero to be numeric)
- // * example 1: $array1 = {'a' : 'green', 0:'red', 1: 'blue'};
- // * example 1: $array2 = {'b' : 'green', 0:'yellow', 1:'red'};
- // * example 1: $array3 = ['green', 'red'];
- // * example 1: $result = array_intersect($array1, $array2, $array3);
- // * returns 1: {0: 'red', a: 'green'}
- var arr1 = arguments[0],
- retArr = {};
- var k1 = '',
- arr = {},
- i = 0,
- k = '';
-
- arr1keys: for (k1 in arr1) {
- arrs: for (i = 1; i < arguments.length; i++) {
- arr = arguments[i];
- for (k in arr) {
- if (arr[k] === arr1[k1]) {
- if (i === arguments.length - 1) {
- retArr[k1] = arr1[k1];
- }
- // If the innermost loop always leads at least once to an equal value, continue the loop until done
- continue arrs;
- }
- }
- // If it reaches here, it wasn't found in at least one array, so try next value
- continue arr1keys;
- }
- }
-
- return retArr;
- };
-
- php.array_key_exists = function (key, search) {
- // Checks if the given key or index exists in the array
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/array_key_exists
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Felix Geisendoerfer (http://www.debuggable.com/felix)
- // * example 1: \php.array_key_exists('kevin', {'kevin': 'van Zonneveld'});
- // * returns 1: true
- // input sanitation
- if (!search || (search.constructor !== Array && search.constructor !== Object)) {
- return false;
- }
-
- return key in search;
- };
-
- php.array_keys = function (input, search_value, argStrict) {
- // Return just the keys from the input array, optionally only for the specified search_value
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/array_keys
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + input by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: jd
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // * example 1: \php.array_keys( {firstname: 'Kevin', surname: 'van Zonneveld'} );
- // * returns 1: {0: 'firstname', 1: 'surname'}
- var search = typeof search_value !== 'undefined',
- tmp_arr = [],
- strict = !!argStrict,
- include = true,
- key = '';
-
- for (key in input) {
- if (input.hasOwnProperty(key)) {
- include = true;
- if (search) {
- if (strict && input[key] !== search_value) {
- include = false;
- }
- else if (input[key] != search_value) {
- include = false;
- }
- }
-
- if (include) {
- tmp_arr[tmp_arr.length] = key;
- }
- }
- }
-
- return tmp_arr;
- };
-
- php.array_map = function (callback) {
- // Applies the callback to the elements in given arrays.
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/array_map
- // + original by: Andrea Giammarchi (http://webreflection.blogspot.com)
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // % note 1: Takes a function as an argument, not a function's name
- // % note 2: If the callback is a string, it can only work if the function name is in the global context
- // * example 1: \php.array_map( function (a){return (a * a * a)}, [1, 2, 3, 4, 5] );
- // * returns 1: [ 1, 8, 27, 64, 125 ]
- var argc = arguments.length,
- argv = arguments;
- var j = argv[1].length,
- i = 0,
- k = 1,
- m = 0;
- var tmp = [],
- tmp_ar = [];
-
- while (i < j) {
- while (k < argc) {
- tmp[m++] = argv[k++][i];
- }
-
- m = 0;
- k = 1;
-
- if (callback) {
- if (typeof callback === 'string') {
- callback = this.window[callback];
- }
- tmp_ar[i++] = callback.apply(null, tmp);
- } else {
- tmp_ar[i++] = tmp;
- }
-
- tmp = [];
- }
-
- return tmp_ar;
- };
-
- php.array_merge = function () {
- // Merges elements from passed arrays into one array
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/array_merge
- // + original by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: Nate
- // + input by: josh
- // + bugfixed by: Brett Zamir (http://brett-zamir.me)
- // * example 1: \php.arr1 = {"color": "red", 0: 2, 1: 4}
- // * example 1: \php.arr2 = {0: "a", 1: "b", "color": "green", "shape": "trapezoid", 2: 4}
- // * example 1: \php.array_merge(arr1, arr2)
- // * returns 1: {"color": "green", 0: 2, 1: 4, 2: "a", 3: "b", "shape": "trapezoid", 4: 4}
- // * example 2: \php.arr1 = []
- // * example 2: \php.arr2 = {1: "data"}
- // * example 2: \php.array_merge(arr1, arr2)
- // * returns 2: {0: "data"}
- var args = Array.prototype.slice.call(arguments),
- retObj = {},
- k, j = 0,
- i = 0,
- retArr = true;
-
- for (i = 0; i < args.length; i++) {
- if (!(args[i] instanceof Array)) {
- retArr = false;
- break;
- }
- }
-
- if (retArr) {
- retArr = [];
- for (i = 0; i < args.length; i++) {
- retArr = retArr.concat(args[i]);
- }
- return retArr;
- }
- var ct = 0;
-
- for (i = 0, ct = 0; i < args.length; i++) {
- if (args[i] instanceof Array) {
- for (j = 0; j < args[i].length; j++) {
- retObj[ct++] = args[i][j];
- }
- } else {
- for (k in args[i]) {
- if (args[i].hasOwnProperty(k)) {
- if (parseInt(k, 10) + '' === k) {
- retObj[ct++] = args[i][k];
- } else {
- retObj[k] = args[i][k];
- }
- }
- }
- }
- }
- return retObj;
- };
-
- php.array_merge_recursive = function (arr1, arr2) {
- // Recursively merges elements from passed arrays into one array
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/array_merge_recursive
- // + original by: Subhasis Deb
- // + input by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // - depends on: array_merge
- // * example 1: \php.arr1 = {'color': {'favourite': 'read'}, 0: 5}
- // * example 1: \php.arr2 = {0: 10, 'color': {'favorite': 'green', 0: 'blue'}}
- // * example 1: \php.array_merge_recursive(arr1, arr2)
- // * returns 1: {'color': {'favorite': {0: 'red', 1: 'green'}, 0: 'blue'}, 1: 5, 1: 10}
- var idx = '';
-
- if ((arr1 && (arr1 instanceof Array)) && (arr2 && (arr2 instanceof Array))) {
- for (idx in arr2) {
- arr1.push(arr2[idx]);
- }
- } else if ((arr1 && (arr1 instanceof Object)) && (arr2 && (arr2 instanceof Object))) {
- for (idx in arr2) {
- if (idx in arr1) {
- if (typeof arr1[idx] == 'object' && typeof arr2 == 'object') {
- arr1[idx] = this.array_merge(arr1[idx], arr2[idx]);
- } else {
- arr1[idx] = arr2[idx];
- }
- } else {
- arr1[idx] = arr2[idx];
- }
- }
- }
-
- return arr1;
- };
-
- php.array_pop = function (inputArr) {
- // Pops an element off the end of the array
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/array_pop
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + input by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfixed by: Brett Zamir (http://brett-zamir.me)
- // + input by: Theriault
- // % note 1: While IE (and other browsers) support iterating an object's
- // % note 1: own properties in order, if one attempts to add back properties
- // % note 1: in IE, they may end up in their former position due to their position
- // % note 1: being retained. So use of this function with "associative arrays"
- // % note 1: (objects) may lead to unexpected behavior in an IE environment if
- // % note 1: you add back properties with the same keys that you removed
- // * example 1: \php.array_pop([0,1,2]);
- // * returns 1: 2
- // * example 2: \php.data = {firstName: 'Kevin', surName: 'van Zonneveld'};
- // * example 2: \php.lastElem = array_pop(data);
- // * returns 2: 'van Zonneveld'
- // * results 2: data == {firstName: 'Kevin'}
- var key = '',
- lastKey = '';
-
- if (inputArr.hasOwnProperty('length')) {
- // Indexed
- if (!inputArr.length) {
- // Done popping, are we?
- return null;
- }
- return inputArr.pop();
- } else {
- // Associative
- for (key in inputArr) {
- if (inputArr.hasOwnProperty(key)) {
- lastKey = key;
- }
- }
- if (lastKey) {
- var tmp = inputArr[lastKey];
- delete(inputArr[lastKey]);
- return tmp;
- } else {
- return null;
- }
- }
- };
-
- php.array_push = function (inputArr) {
- // Pushes elements onto the end of the array
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/array_push
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // % note 1: Note also that IE retains information about property position even
- // % note 1: after being supposedly deleted, so if you delete properties and then
- // % note 1: add back properties with the same keys (including numeric) that had
- // % note 1: been deleted, the order will be as before; thus, this function is not
- // % note 1: really recommended with associative arrays (objects) in IE environments
- // * example 1: \php.array_push(['kevin','van'], 'zonneveld');
- // * returns 1: 3
- var i = 0,
- pr = '',
- argv = arguments,
- argc = argv.length,
- allDigits = /^\d$/,
- size = 0,
- highestIdx = 0,
- len = 0;
- if (inputArr.hasOwnProperty('length')) {
- for (i = 1; i < argc; i++) {
- inputArr[inputArr.length] = argv[i];
- }
- return inputArr.length;
- }
-
- // Associative (object)
- for (pr in inputArr) {
- if (inputArr.hasOwnProperty(pr)) {
- ++len;
- if (pr.search(allDigits) !== -1) {
- size = parseInt(pr, 10);
- highestIdx = size > highestIdx ? size : highestIdx;
- }
- }
- }
- for (i = 1; i < argc; i++) {
- inputArr[++highestIdx] = argv[i];
- }
- return len + i - 1;
- };
-
- php.array_reduce = function (a_input, callback) {
- // Iteratively reduce the array to a single value via the callback.
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/array_reduce
- // + original by: Alfonso Jimenez (http://www.alfonsojimenez.com)
- // % note 1: Takes a function as an argument, not a function's name
- // * example 1: \php.array_reduce([1, 2, 3, 4, 5], function (v, w){v += w;return v;});
- // * returns 1: 15
- var lon = a_input.length;
- var res = 0,
- i = 0;
- var tmp = [];
-
-
- for (i = 0; i < lon; i += 2) {
- tmp[0] = a_input[i];
- if (a_input[(i + 1)]) {
- tmp[1] = a_input[(i + 1)];
- } else {
- tmp[1] = 0;
- }
- res += callback.apply(null, tmp);
- tmp = [];
- }
-
- return res;
- };
-
- php.array_reverse = function (array, preserve_keys) {
- // Return input as a new array with the order of the entries reversed
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/array_reverse
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Karol Kowalski
- // * example 1: \php.array_reverse( [ 'php', '4.0', ['green', 'red'] ], true);
- // * returns 1: { 2: ['green', 'red'], 1: 4, 0: 'php'}
- var arr_len = array.length,
- newkey = 0,
- tmp_arr = {},
- key = '';
- preserve_keys = !! preserve_keys;
-
- for (key in array) {
- newkey = arr_len - key - 1;
- tmp_arr[preserve_keys ? key : newkey] = array[key];
- }
-
- return tmp_arr;
- };
-
- php.array_shift = function (inputArr) {
- // Pops an element off the beginning of the array
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/array_shift
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Martijn Wieringa
- // % note 1: Currently does not handle objects
- // * example 1: \php.array_shift(['Kevin', 'van', 'Zonneveld']);
- // * returns 1: 'Kevin'
- var props = false,
- shift = undefined,
- pr = '',
- allDigits = /^\d$/,
- int_ct = -1,
- _checkToUpIndices = function (arr, ct, key) {
- // Deal with situation, e.g., if encounter index 4 and try to set it to 0, but 0 exists later in loop (need to
- // increment all subsequent (skipping current key, since we need its value below) until find unused)
- if (arr[ct] !== undefined) {
- var tmp = ct;
- ct += 1;
- if (ct === key) {
- ct += 1;
- }
- ct = _checkToUpIndices(arr, ct, key);
- arr[ct] = arr[tmp];
- delete arr[tmp];
- }
- return ct;
- };
-
-
- if (inputArr.length === 0) {
- return null;
- }
- if (inputArr.length > 0) {
- return inputArr.shift();
- }
-
- /*
- UNFINISHED FOR HANDLING OBJECTS
- for (pr in inputArr) {
- if (inputArr.hasOwnProperty(pr)) {
- props = true;
- shift = inputArr[pr];
- delete inputArr[pr];
- break;
- }
- }
- for (pr in inputArr) {
- if (inputArr.hasOwnProperty(pr)) {
- if (pr.search(allDigits) !== -1) {
- int_ct += 1;
- if (parseInt(pr, 10) === int_ct) { // Key is already numbered ok, so don't need to change key for value
- continue;
- }
- _checkToUpIndices(inputArr, int_ct, pr);
- arr[int_ct] = arr[pr];
- delete arr[pr];
- }
- }
- }
- if (!props) {
- return null;
- }
- return shift;
- */
- };
-
- php.array_slice = function (arr, offst, lgth, preserve_keys) {
- // Returns elements specified by offset and length
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/array_slice
- // + original by: Brett Zamir (http://brett-zamir.me)
- // - depends on: is_int
- // + input by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // % note: Relies on is_int because !isNaN accepts floats
- // * example 1: \php.array_slice(["a", "b", "c", "d", "e"], 2, -1);
- // * returns 1: {0: 'c', 1: 'd'}
- // * example 2: \php.array_slice(["a", "b", "c", "d", "e"], 2, -1, true);
- // * returns 2: {2: 'c', 3: 'd'}
- /*
- if ('callee' in arr && 'length' in arr) {
- arr = Array.prototype.slice.call(arr);
- }
- */
-
- var key = '';
-
- if (!(arr instanceof Array) || (preserve_keys && offst !== 0)) { // Assoc. array as input or if required as output
- var lgt = 0,
- newAssoc = {};
- for (key in arr) {
- //if (key !== 'length') {
- lgt += 1;
- newAssoc[key] = arr[key];
- //}
- }
- arr = newAssoc;
-
- offst = (offst < 0) ? lgt + offst : offst;
- lgth = lgth === undefined ? lgt : (lgth < 0) ? lgt + lgth - offst : lgth;
-
- var assoc = {};
- var start = false,
- it = -1,
- arrlgth = 0,
- no_pk_idx = 0;
- for (key in arr) {
- ++it;
- if (arrlgth >= lgth) {
- break;
- }
- if (it == offst) {
- start = true;
- }
- if (!start) {
- continue;
- }++arrlgth;
- if (this.is_int(key) && !preserve_keys) {
- assoc[no_pk_idx++] = arr[key];
- } else {
- assoc[key] = arr[key];
- }
- }
- //assoc.length = arrlgth; // Make as array-like object (though length will not be dynamic)
- return assoc;
- }
-
- if (lgth === undefined) {
- return arr.slice(offst);
- } else if (lgth >= 0) {
- return arr.slice(offst, offst + lgth);
- } else {
- return arr.slice(offst, lgth);
- }
- };
-
- php.array_splice = function (arr, offst, lgth, replacement) {
- // Removes the elements designated by offset and length and replace them with supplied array
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/array_splice
- // + original by: Brett Zamir (http://brett-zamir.me)
- // + input by: Theriault
- // % note 1: Order does get shifted in associative array input with numeric indices,
- // % note 1: since PHP behavior doesn't preserve keys, but I understand order is
- // % note 1: not reliable anyways
- // % note 2: Note also that IE retains information about property position even
- // % note 2: after being supposedly deleted, so use of this function may produce
- // % note 2: unexpected results in IE if you later attempt to add back properties
- // % note 2: with the same keys that had been deleted
- // - depends on: is_int
- // * example 1: \php.input = {4: "red", 'abc': "green", 2: "blue", 'dud': "yellow"};
- // * example 1: \php.array_splice(input, 2);
- // * returns 1: {0: "blue", 'dud': "yellow"}
- // * results 1: input == {'abc':"green", 0:"red"}
- // * example 2: \php.input = ["red", "green", "blue", "yellow"];
- // * example 2: \php.array_splice(input, 3, 0, "purple");
- // * returns 2: []
- // * results 2: input == ["red", "green", "blue", "purple", "yellow"]
- // * example 3: \php.input = ["red", "green", "blue", "yellow"]
- // * example 3: \php.array_splice(input, -1, 1, ["black", "maroon"]);
- // * returns 3: ["yellow"]
- // * results 3: input == ["red", "green", "blue", "black", "maroon"]
- var _checkToUpIndices = function (arr, ct, key) {
- // Deal with situation, e.g., if encounter index 4 and try to set it to 0, but 0 exists later in loop (need to
- // increment all subsequent (skipping current key, since we need its value below) until find unused)
- if (arr[ct] !== undefined) {
- var tmp = ct;
- ct += 1;
- if (ct === key) {
- ct += 1;
- }
- ct = _checkToUpIndices(arr, ct, key);
- arr[ct] = arr[tmp];
- delete arr[tmp];
- }
- return ct;
- };
-
- if (replacement && typeof replacement !== 'object') {
- replacement = [replacement];
- }
- if (lgth === undefined) {
- lgth = offst >= 0 ? arr.length - offst : -offst;
- } else if (lgth < 0) {
- lgth = (offst >= 0 ? arr.length - offst : -offst) + lgth;
- }
-
- if (!(arr instanceof Array)) {
- /*if (arr.length !== undefined) { // Deal with array-like objects as input
- delete arr.length;
- }*/
- var lgt = 0,
- ct = -1,
- rmvd = [],
- rmvdObj = {},
- repl_ct = -1,
- int_ct = -1;
- var returnArr = true,
- rmvd_ct = 0,
- rmvd_lgth = 0,
- key = '';
- // rmvdObj.length = 0;
- for (key in arr) { // Can do arr.__count__ in some browsers
- lgt += 1;
- }
- offst = (offst >= 0) ? offst : lgt + offst;
- for (key in arr) {
- ct += 1;
- if (ct < offst) {
- if (this.is_int(key)) {
- int_ct += 1;
- if (parseInt(key, 10) === int_ct) { // Key is already numbered ok, so don't need to change key for value
- continue;
- }
- _checkToUpIndices(arr, int_ct, key); // Deal with situation, e.g.,
- // if encounter index 4 and try to set it to 0, but 0 exists later in loop
- arr[int_ct] = arr[key];
- delete arr[key];
- }
- continue;
- }
- if (returnArr && this.is_int(key)) {
- rmvd.push(arr[key]);
- rmvdObj[rmvd_ct++] = arr[key]; // PHP starts over here too
- } else {
- rmvdObj[key] = arr[key];
- returnArr = false;
- }
- rmvd_lgth += 1;
- // rmvdObj.length += 1;
- if (replacement && replacement[++repl_ct]) {
- arr[key] = replacement[repl_ct];
- } else {
- delete arr[key];
- }
- }
- // arr.length = lgt - rmvd_lgth + (replacement ? replacement.length : 0); // Make (back) into an array-like object
- return returnArr ? rmvd : rmvdObj;
- }
-
- if (replacement) {
- replacement.unshift(offst, lgth);
- return Array.prototype.splice.apply(arr, replacement);
- }
- return arr.splice(offst, lgth);
- };
-
- php.array_sum = function (array) {
- // Returns the sum of the array entries
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/array_sum
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfixed by: Nate
- // + bugfixed by: Gilbert
- // * example 1: \php.array_sum([4, 9, 182.6]);
- // * returns 1: 195.6
- // * example 2: \php.total = []; index = 0.1; for (y=0; y < 12; y++){total[y] = y + index;}
- // * example 2: \php.array_sum(total);
- // * returns 2: 67.2
- var key, sum = 0;
-
- // input sanitation
- if (typeof array !== 'object') {
- return null;
- }
-
- for (key in array) {
- //tester_print_r(typeof sum);
- sum += (array[key] * 1);
- }
-
- return sum;
- };
-
- php.array_unique = function (inputArr) {
- // Removes duplicate values from array
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/array_unique
- // + original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com)
- // + input by: duncan
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfixed by: Nate
- // + input by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Michael Grier
- // + bugfixed by: Brett Zamir (http://brett-zamir.me)
- // % note 1: The second argument, sort_flags is not implemented;
- // % note 1: also should be sorted (asort?) first according to docs
- // * example 1: \php.array_unique(['Kevin','Kevin','van','Zonneveld','Kevin']);
- // * returns 1: {0: 'Kevin', 2: 'van', 3: 'Zonneveld'}
- // * example 2: \php.array_unique({'a': 'green', 0: 'red', 'b': 'green', 1: 'blue', 2: 'red'});
- // * returns 2: {a: 'green', 0: 'red', 1: 'blue'}
- var key = '',
- tmp_arr2 = {},
- val = '';
-
- var __array_search = function (needle, haystack) {
- var fkey = '';
- for (fkey in haystack) {
- if (haystack.hasOwnProperty(fkey)) {
- if ((haystack[fkey] + '') === (needle + '')) {
- return fkey;
- }
- }
- }
- return false;
- };
-
- for (key in inputArr) {
- if (inputArr.hasOwnProperty(key)) {
- val = inputArr[key];
- if (false === __array_search(val, tmp_arr2)) {
- tmp_arr2[key] = val;
- }
- }
- }
-
- return tmp_arr2;
- };
-
- php.array_unshift = function (array) {
- // Pushes elements onto the beginning of the array
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/array_unshift
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Martijn Wieringa
- // + improved by: jmweb
- // % note 1: Currently does not handle objects
- // * example 1: \php.array_unshift(['van', 'Zonneveld'], 'Kevin');
- // * returns 1: 3
- var i = arguments.length;
-
- while (--i !== 0) {
- arguments[0].unshift(arguments[i]);
- }
-
- return arguments[0].length;
- };
-
- php.array_values = function (input) {
- // Return just the values from the input array
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/array_values
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // * example 1: \php.array_values( {firstname: 'Kevin', surname: 'van Zonneveld'} );
- // * returns 1: {0: 'Kevin', 1: 'van Zonneveld'}
- var tmp_arr = [],
- cnt = 0;
- var key = '';
-
- for (key in input) {
- tmp_arr[cnt] = input[key];
- cnt++;
- }
-
- return tmp_arr;
- };
-
- php.array_walk = function (array, funcname, userdata) {
- // Apply a user function to every member of an array
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/array_walk
- // + original by: Johnny Mast (http://www.phpvrouwen.nl)
- // * example 1: \php.array_walk ({'a':'b'}, 'void', 'userdata');
- // * returns 1: true
- // * example 2: \php.array_walk ('a', 'void', 'userdata');
- // * returns 2: false
- var key;
-
- if (typeof array !== 'object' || array === null) {
- return false;
- }
-
- for (key in array) {
- if (typeof(userdata) !== 'undefined') {
- eval(funcname + '( array [key] , key , userdata )');
- } else {
- eval(funcname + '( userdata ) ');
- }
- }
-
- return true;
- };
-
- php.array_walk_recursive = function (array, funcname, userdata) {
- // Apply a user function recursively to every member of an array
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/array_walk_recursive
- // + original by: Johnny Mast (http://www.phpvrouwen.nl)
- // * example 1: \php.array_walk_recursive ({'a': 'b', 'c': {'d': 'e'}}, 'void', 'userdata');
- // * returns 1: true
- // * example 2: \php.array_walk_recursive ('a', 'void', 'userdata');
- // * returns 2: false
- var key;
-
- if (typeof array != 'object') {
- return false;
- }
-
- for (key in array) {
- if (typeof array[key] == 'object') {
- return this.array_walk_recursive(array[key], funcname, userdata);
- }
-
- if (typeof(userdata) != 'undefined') {
- eval(funcname + '( array [key] , key , userdata )');
- } else {
- eval(funcname + '( userdata ) ');
- }
- }
-
- return true;
- };
-
- php.arsort = function (inputArr, sort_flags) {
- // Sort an array in reverse order and maintain index association
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/arsort
- // + original by: Brett Zamir (http://brett-zamir.me)
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // % note 1: SORT_STRING (as well as natsort and natcasesort) might also be
- // % note 1: integrated into all of these functions by adapting the code at
- // % note 1: http://sourcefrog.net/projects/natsort/natcompare.js
- // % note 2: The examples are correct, this is a new way
- // % note 2: Credits to: http://javascript.internet.com/math-related/bubble-sort.html
- // % note 3: This function deviates from PHP in returning a copy of the array instead
- // % note 3: of acting by reference and returning true; this was necessary because
- // % note 3: IE does not allow deleting and re-adding of properties without caching
- // % note 3: of property position; you can set the ini of "phpjs.strictForIn" to true to
- // % note 3: get the PHP behavior, but use this only if you are in an environment
- // % note 3: such as Firefox extensions where for-in iteration order is fixed and true
- // % note 3: property deletion is supported. Note that we intend to implement the PHP
- // % note 3: behavior by default if IE ever does allow it; only gives shallow copy since
- // % note 3: is by reference in PHP anyways
- // % note 4: Since JS objects' keys are always strings, and (the
- // % note 4: default) SORT_REGULAR flag distinguishes by key type,
- // % note 4: if the content is a numeric string, we treat the
- // % note 4: "original type" as numeric.
- // - depends on: i18n_loc_get_default
- // * example 1: \php.data = {d: 'lemon', a: 'orange', b: 'banana', c: 'apple'};
- // * example 1: \php.data = arsort(data);
- // * returns 1: data == {a: 'orange', d: 'lemon', b: 'banana', c: 'apple'}
- // * example 2: \php.ini_set('phpjs.strictForIn', true);
- // * example 2: \php.data = {d: 'lemon', a: 'orange', b: 'banana', c: 'apple'};
- // * example 2: \php.arsort(data);
- // * results 2: data == {a: 'orange', d: 'lemon', b: 'banana', c: 'apple'}
- // * returns 2: true
- var valArr = [],
- keyArr = [],
- k, i, ret, sorter, that = this,
- strictForIn = false,
- populateArr = {};
-
- switch (sort_flags) {
- case 'SORT_STRING':
- // compare items as strings
- sorter = function (a, b) {
- return that.strnatcmp(b, a);
- };
- break;
- case 'SORT_LOCALE_STRING':
- // compare items as strings, based on the current locale (set with i18n_loc_set_default() as of PHP6)
- var loc = this.i18n_loc_get_default();
- sorter = this.php_js.i18nLocales[loc].sorting;
- break;
- case 'SORT_NUMERIC':
- // compare items numerically
- sorter = function (a, b) {
- return (a - b);
- };
- break;
- case 'SORT_REGULAR':
- // compare items normally (don't change types)
- default:
- sorter = function (b, a) {
- var aFloat = parseFloat(a),
- bFloat = parseFloat(b),
- aNumeric = aFloat + '' === a,
- bNumeric = bFloat + '' === b;
- if (aNumeric && bNumeric) {
- return aFloat > bFloat ? 1 : aFloat < bFloat ? -1 : 0;
- } else if (aNumeric && !bNumeric) {
- return 1;
- } else if (!aNumeric && bNumeric) {
- return -1;
- }
- return a > b ? 1 : a < b ? -1 : 0;
- };
- break;
- }
-
- var bubbleSort = function (keyArr, inputArr) {
- var i, j, tempValue, tempKeyVal;
- for (i = inputArr.length - 2; i >= 0; i--) {
- for (j = 0; j <= i; j++) {
- ret = sorter(inputArr[j + 1], inputArr[j]);
- if (ret > 0) {
- tempValue = inputArr[j];
- inputArr[j] = inputArr[j + 1];
- inputArr[j + 1] = tempValue;
- tempKeyVal = keyArr[j];
- keyArr[j] = keyArr[j + 1];
- keyArr[j + 1] = tempKeyVal;
- }
- }
- }
- };
-
- // BEGIN REDUNDANT
- this.php_js = this.php_js || {};
- this.php_js.ini = this.php_js.ini || {};
- // END REDUNDANT
- strictForIn = this.php_js.ini['phpjs.strictForIn'] && this.php_js.ini['phpjs.strictForIn'].local_value && this.php_js.ini['phpjs.strictForIn'].local_value !== 'off';
- populateArr = strictForIn ? inputArr : populateArr;
-
-
- // Get key and value arrays
- for (k in inputArr) {
- if (inputArr.hasOwnProperty(k)) {
- valArr.push(inputArr[k]);
- keyArr.push(k);
- if (strictForIn) {
- delete inputArr[k];
- }
- }
- }
- try {
- // Sort our new temporary arrays
- bubbleSort(keyArr, valArr);
- } catch (e) {
- return false;
- }
-
- // Repopulate the old array
- for (i = 0; i < valArr.length; i++) {
- populateArr[keyArr[i]] = valArr[i];
- }
-
- return strictForIn || populateArr;
- };
-
- php.asort = function (inputArr, sort_flags) {
- // Sort an array and maintain index association
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/asort
- // + original by: Brett Zamir (http://brett-zamir.me)
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // + input by: paulo kuong
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: Adam Wallner (http://web2.bitbaro.hu/)
- // % note 1: SORT_STRING (as well as natsort and natcasesort) might also be
- // % note 1: integrated into all of these functions by adapting the code at
- // % note 1: http://sourcefrog.net/projects/natsort/natcompare.js
- // % note 2: The examples are correct, this is a new way
- // % note 2: Credits to: http://javascript.internet.com/math-related/bubble-sort.html
- // % note 3: This function deviates from PHP in returning a copy of the array instead
- // % note 3: of acting by reference and returning true; this was necessary because
- // % note 3: IE does not allow deleting and re-adding of properties without caching
- // % note 3: of property position; you can set the ini of "phpjs.strictForIn" to true to
- // % note 3: get the PHP behavior, but use this only if you are in an environment
- // % note 3: such as Firefox extensions where for-in iteration order is fixed and true
- // % note 3: property deletion is supported. Note that we intend to implement the PHP
- // % note 3: behavior by default if IE ever does allow it; only gives shallow copy since
- // % note 3: is by reference in PHP anyways
- // % note 4: Since JS objects' keys are always strings, and (the
- // % note 4: default) SORT_REGULAR flag distinguishes by key type,
- // % note 4: if the content is a numeric string, we treat the
- // % note 4: "original type" as numeric.
- // - depends on: strnatcmp
- // - depends on: i18n_loc_get_default
- // * example 1: \php.data = {d: 'lemon', a: 'orange', b: 'banana', c: 'apple'};
- // * example 1: \php.data = asort(data);
- // * results 1: data == {c: 'apple', b: 'banana', d: 'lemon', a: 'orange'}
- // * returns 1: true
- // * example 2: \php.ini_set('phpjs.strictForIn', true);
- // * example 2: \php.data = {d: 'lemon', a: 'orange', b: 'banana', c: 'apple'};
- // * example 2: \php.asort(data);
- // * results 2: data == {c: 'apple', b: 'banana', d: 'lemon', a: 'orange'}
- // * returns 2: true
- var valArr = [],
- keyArr = [],
- k, i, ret, sorter, that = this,
- strictForIn = false,
- populateArr = {};
-
- switch (sort_flags) {
- case 'SORT_STRING':
- // compare items as strings
- sorter = function (a, b) {
- return that.strnatcmp(a, b);
- };
- break;
- case 'SORT_LOCALE_STRING':
- // compare items as strings, based on the current locale (set with i18n_loc_set_default() as of PHP6)
- var loc = this.i18n_loc_get_default();
- sorter = this.php_js.i18nLocales[loc].sorting;
- break;
- case 'SORT_NUMERIC':
- // compare items numerically
- sorter = function (a, b) {
- return (a - b);
- };
- break;
- case 'SORT_REGULAR':
- // compare items normally (don't change types)
- default:
- sorter = function (a, b) {
- var aFloat = parseFloat(a),
- bFloat = parseFloat(b),
- aNumeric = aFloat + '' === a,
- bNumeric = bFloat + '' === b;
- if (aNumeric && bNumeric) {
- return aFloat > bFloat ? 1 : aFloat < bFloat ? -1 : 0;
- } else if (aNumeric && !bNumeric) {
- return 1;
- } else if (!aNumeric && bNumeric) {
- return -1;
- }
- return a > b ? 1 : a < b ? -1 : 0;
- };
- break;
- }
-
- var bubbleSort = function (keyArr, inputArr) {
- var i, j, tempValue, tempKeyVal;
- for (i = inputArr.length - 2; i >= 0; i--) {
- for (j = 0; j <= i; j++) {
- ret = sorter(inputArr[j + 1], inputArr[j]);
- if (ret < 0) {
- tempValue = inputArr[j];
- inputArr[j] = inputArr[j + 1];
- inputArr[j + 1] = tempValue;
- tempKeyVal = keyArr[j];
- keyArr[j] = keyArr[j + 1];
- keyArr[j + 1] = tempKeyVal;
- }
- }
- }
- };
-
- // BEGIN REDUNDANT
- this.php_js = this.php_js || {};
- this.php_js.ini = this.php_js.ini || {};
- // END REDUNDANT
- strictForIn = this.php_js.ini['phpjs.strictForIn'] && this.php_js.ini['phpjs.strictForIn'].local_value && this.php_js.ini['phpjs.strictForIn'].local_value !== 'off';
- populateArr = strictForIn ? inputArr : populateArr;
-
- // Get key and value arrays
- for (k in inputArr) {
- if (inputArr.hasOwnProperty(k)) {
- valArr.push(inputArr[k]);
- keyArr.push(k);
- if (strictForIn) {
- delete inputArr[k];
- }
- }
- }
- try {
- // Sort our new temporary arrays
- bubbleSort(keyArr, valArr);
- } catch (e) {
- return false;
- }
-
- // Repopulate the old array
- for (i = 0; i < valArr.length; i++) {
- populateArr[keyArr[i]] = valArr[i];
- }
-
- return strictForIn || populateArr;
- };
-
- php.base64_decode = function (data) {
- // Decodes string using MIME base64 algorithm
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/base64_decode
- // + original by: Tyler Akins (http://rumkin.com)
- // + improved by: Thunder.m
- // + input by: Aman Gupta
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfixed by: Onno Marsman
- // + bugfixed by: Pellentesque Malesuada
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + input by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // - depends on: utf8_decode
- // * example 1: \php.base64_decode('S2V2aW4gdmFuIFpvbm5ldmVsZA==');
- // * returns 1: 'Kevin van Zonneveld'
- // mozilla has this native
- // - but breaks in 2.0.0.12!
- //if (typeof this.window['btoa'] == 'function') {
- // return btoa(data);
- //}
- var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
- var o1, o2, o3, h1, h2, h3, h4, bits, i = 0,
- ac = 0,
- dec = "",
- tmp_arr = [];
-
- if (!data) {
- return data;
- }
-
- data += '';
-
- do { // unpack four hexets into three octets using index points in b64
- h1 = b64.indexOf(data.charAt(i++));
- h2 = b64.indexOf(data.charAt(i++));
- h3 = b64.indexOf(data.charAt(i++));
- h4 = b64.indexOf(data.charAt(i++));
-
- bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;
-
- o1 = bits >> 16 & 0xff;
- o2 = bits >> 8 & 0xff;
- o3 = bits & 0xff;
-
- if (h3 == 64) {
- tmp_arr[ac++] = String.fromCharCode(o1);
- } else if (h4 == 64) {
- tmp_arr[ac++] = String.fromCharCode(o1, o2);
- } else {
- tmp_arr[ac++] = String.fromCharCode(o1, o2, o3);
- }
- } while (i < data.length);
-
- dec = tmp_arr.join('');
- dec = this.utf8_decode(dec);
-
- return dec;
- };
-
- php.base64_encode = function (data) {
- // Encodes string using MIME base64 algorithm
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/base64_encode
- // + original by: Tyler Akins (http://rumkin.com)
- // + improved by: Bayron Guevara
- // + improved by: Thunder.m
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfixed by: Pellentesque Malesuada
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // - depends on: utf8_encode
- // * example 1: \php.base64_encode('Kevin van Zonneveld');
- // * returns 1: 'S2V2aW4gdmFuIFpvbm5ldmVsZA=='
- // mozilla has this native
- // - but breaks in 2.0.0.12!
- //if (typeof this.window['atob'] == 'function') {
- // return atob(data);
- //}
- var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
- var o1, o2, o3, h1, h2, h3, h4, bits, i = 0,
- ac = 0,
- enc = "",
- tmp_arr = [];
-
- if (!data) {
- return data;
- }
-
- data = this.utf8_encode(data + '');
-
- do { // pack three octets into four hexets
- o1 = data.charCodeAt(i++);
- o2 = data.charCodeAt(i++);
- o3 = data.charCodeAt(i++);
-
- bits = o1 << 16 | o2 << 8 | o3;
-
- h1 = bits >> 18 & 0x3f;
- h2 = bits >> 12 & 0x3f;
- h3 = bits >> 6 & 0x3f;
- h4 = bits & 0x3f;
-
- // use hexets to index into b64, and append result to encoded string
- tmp_arr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4);
- } while (i < data.length);
-
- enc = tmp_arr.join('');
-
- switch (data.length % 3) {
- case 1:
- enc = enc.slice(0, -2) + '==';
- break;
- case 2:
- enc = enc.slice(0, -1) + '=';
- break;
- }
-
- return enc;
- };
-
- php.base_convert = function (number, frombase, tobase) {
- // Converts a number in a string from any base <= 36 to any base <= 36
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/base_convert
- // + original by: Philippe Baumann
- // + improved by: Rafał Kukawski (http://blog.kukawski.pl)
- // * example 1: \php.base_convert('A37334', 16, 2);
- // * returns 1: '101000110111001100110100'
- return parseInt(number + '', frombase | 0).toString(tobase | 0);
- };
-
- php.basename = function (path, suffix) {
- // Returns the filename component of the path
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/basename
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Ash Searle (http://hexmen.com/blog/)
- // + improved by: Lincoln Ramsay
- // + improved by: djmix
- // * example 1: \php.basename('/www/site/home.htm', '.htm');
- // * returns 1: 'home'
- // * example 2: \php.basename('ecra.php?p=1');
- // * returns 2: 'ecra.php?p=1'
- var b = path.replace(/^.*[\/\\]/g, '');
-
- if (typeof(suffix) == 'string' && b.substr(b.length - suffix.length) == suffix) {
- b = b.substr(0, b.length - suffix.length);
- }
-
- return b;
- };
-
- php.call_user_func = function (cb) {
- // Call a user function which is the first parameter
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/call_user_func
- // + original by: Brett Zamir (http://brett-zamir.me)
- // + improved by: Diplom@t (http://difane.com/)
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // * example 1: \php.call_user_func('isNaN', 'a');
- // * returns 1: true
- var func;
-
- if (typeof cb === 'string') {
- func = (typeof this[cb] === 'function') ? this[cb] : func = (new Function(null, 'return ' + cb))();
- } else if (cb instanceof Array) {
- func = (typeof cb[0] == 'string') ? eval(cb[0] + "['" + cb[1] + "']") : func = cb[0][cb[1]];
- } else if (typeof cb === 'function') {
- func = cb;
- }
-
- if (typeof func != 'function') {
- throw new Error(func + ' is not a valid function');
- }
-
- var parameters = Array.prototype.slice.call(arguments, 1);
- return (typeof cb[0] === 'string') ? func.apply(eval(cb[0]), parameters) : (typeof cb[0] !== 'object') ? func.apply(null, parameters) : func.apply(cb[0], parameters);
- };
-
- php.call_user_func_array = function (cb, parameters) {
- // Call a user function which is the first parameter with the arguments contained in array
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/call_user_func_array
- // + original by: Thiago Mata (http://thiagomata.blog.com)
- // + revised by: Jon Hohle
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // + improved by: Diplom@t (http://difane.com/)
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // * example 1: \php.call_user_func_array('isNaN', ['a']);
- // * returns 1: true
- // * example 2: \php.call_user_func_array('isNaN', [1]);
- // * returns 2: false
- var func;
-
- if (typeof cb === 'string') {
- func = (typeof this[cb] === 'function') ? this[cb] : func = (new Function(null, 'return ' + cb))();
- } else if (cb instanceof Array) {
- func = (typeof cb[0] == 'string') ? eval(cb[0] + "['" + cb[1] + "']") : func = cb[0][cb[1]];
- } else if (typeof cb === 'function') {
- func = cb;
- }
-
- if (typeof func !== 'function') {
- throw new Error(func + ' is not a valid function');
- }
-
- return (typeof cb[0] === 'string') ? func.apply(eval(cb[0]), parameters) : (typeof cb[0] !== 'object') ? func.apply(null, parameters) : func.apply(cb[0], parameters);
- };
-
- php.ceil = function (value) {
- // Returns the next highest integer value of the number
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/ceil
- // + original by: Onno Marsman
- // * example 1: \php.ceil(8723321.4);
- // * returns 1: 8723322
- return Math.ceil(value);
- };
-
- php.chr = function (codePt) {
- // Converts a codepoint number to a character
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/chr
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // * example 1: \php.chr(75);
- // * returns 1: 'K'
- // * example 1: \php.chr(65536) === '\uD800\uDC00';
- // * returns 1: true
- if (codePt > 0xFFFF) { // Create a four-byte string (length 2) since this code point is high
- // enough for the UTF-16 encoding (JavaScript internal use), to
- // require representation with two surrogates (reserved non-characters
- // used for building other characters; the first is "high" and the next "low")
- codePt -= 0x10000;
- return String.fromCharCode(0xD800 + (codePt >> 10), 0xDC00 + (codePt & 0x3FF));
- }
- return String.fromCharCode(codePt);
- };
-
- php.class_exists = function (cls) {
- // Checks if the class exists
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/class_exists
- // + original by: Brett Zamir (http://brett-zamir.me)
- // * example 1: \php.function class_a() {this.meth1 = function () {return true;}};
- // * example 1: \php.var instance_a = new class_a();
- // * example 1: \php.class_exists('class_a');
- // * returns 1: true
- var i = '';
- cls = this.window[cls]; // Note: will prevent inner classes
- if (typeof cls !== 'function') {
- return false;
- }
-
- for (i in cls.prototype) {
- return true;
- }
- for (i in cls) { // If static members exist, then consider a "class"
- if (i !== 'prototype') {
- return true;
- }
- }
- if (cls.toSource && cls.toSource().match(/this\./)) {
- // Hackish and non-standard but can probably detect if setting
- // a property (we don't want to test by instantiating as that
- // may have side-effects)
- return true;
- }
-
- return false;
- };
-
- php.compact = function () {
- // Creates a hash containing variables and their values
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/compact
- // + original by: Waldo Malqui Silva
- // + tweaked by: Jack
- // + input by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // * example 1: \php.var1 = 'Kevin'; var2 = 'van'; var3 = 'Zonneveld';
- // * example 1: \php.compact('var1', 'var2', 'var3');
- // * returns 1: {'var1': 'Kevin', 'var2': 'van', 'var3': 'Zonneveld'}
- var matrix = {},
- that = this;
-
- var process = function (value) {
- var i = 0,
- l = value.length,
- key_value = '';
- for (i = 0; i < l; i++) {
- key_value = value[i];
- if (key_value instanceof Array) {
- process(key_value);
- } else {
- if (typeof that.window[key_value] !== 'undefined') {
- matrix[key_value] = that.window[key_value];
- }
- }
- }
- return true;
- };
-
- process(arguments);
- return matrix;
- };
-
- php.count = function (mixed_var, mode) {
- // Count the number of elements in a variable (usually an array)
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/count
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + input by: Waldo Malqui Silva
- // + bugfixed by: Soren Hansen
- // + input by: merabi
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: Olivier Louvignes (http://mg-crea.com/)
- // * example 1: \php.count([[0,0],[0,-4]], 'COUNT_RECURSIVE');
- // * returns 1: 6
- // * example 2: \php.count({'one' : [1,2,3,4,5]}, 'COUNT_RECURSIVE');
- // * returns 2: 6
- var key, cnt = 0;
-
- if (mixed_var === null || typeof mixed_var === 'undefined') {
- return 0;
- } else if (mixed_var.constructor !== Array && mixed_var.constructor !== Object) {
- return 1;
- }
-
- if (mode === 'COUNT_RECURSIVE') {
- mode = 1;
- }
- if (mode != 1) {
- mode = 0;
- }
-
- for (key in mixed_var) {
- if (mixed_var.hasOwnProperty(key)) {
- cnt++;
- if (mode == 1 && mixed_var[key] && (mixed_var[key].constructor === Array || mixed_var[key].constructor === Object)) {
- cnt += this.count(mixed_var[key], 1);
- }
- }
- }
-
- return cnt;
- };
-
- php.crc32 = function (str) {
- // Calculate the crc32 polynomial of a string
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/crc32
- // + original by: Webtoolkit.info (http://www.webtoolkit.info/)
- // + improved by: T0bsn
- // - depends on: utf8_encode
- // * example 1: \php.crc32('Kevin van Zonneveld');
- // * returns 1: 1249991249
- str = this.utf8_encode(str);
- var table = "00000000 77073096 EE0E612C 990951BA 076DC419 706AF48F E963A535 9E6495A3 0EDB8832 79DCB8A4 E0D5E91E 97D2D988 09B64C2B 7EB17CBD E7B82D07 90BF1D91 1DB71064 6AB020F2 F3B97148 84BE41DE 1ADAD47D 6DDDE4EB F4D4B551 83D385C7 136C9856 646BA8C0 FD62F97A 8A65C9EC 14015C4F 63066CD9 FA0F3D63 8D080DF5 3B6E20C8 4C69105E D56041E4 A2677172 3C03E4D1 4B04D447 D20D85FD A50AB56B 35B5A8FA 42B2986C DBBBC9D6 ACBCF940 32D86CE3 45DF5C75 DCD60DCF ABD13D59 26D930AC 51DE003A C8D75180 BFD06116 21B4F4B5 56B3C423 CFBA9599 B8BDA50F 2802B89E 5F058808 C60CD9B2 B10BE924 2F6F7C87 58684C11 C1611DAB B6662D3D 76DC4190 01DB7106 98D220BC EFD5102A 71B18589 06B6B51F 9FBFE4A5 E8B8D433 7807C9A2 0F00F934 9609A88E E10E9818 7F6A0DBB 086D3D2D 91646C97 E6635C01 6B6B51F4 1C6C6162 856530D8 F262004E 6C0695ED 1B01A57B 8208F4C1 F50FC457 65B0D9C6 12B7E950 8BBEB8EA FCB9887C 62DD1DDF 15DA2D49 8CD37CF3 FBD44C65 4DB26158 3AB551CE A3BC0074 D4BB30E2 4ADFA541 3DD895D7 A4D1C46D D3D6F4FB 4369E96A 346ED9FC AD678846 DA60B8D0 44042D73 33031DE5 AA0A4C5F DD0D7CC9 5005713C 270241AA BE0B1010 C90C2086 5768B525 206F85B3 B966D409 CE61E49F 5EDEF90E 29D9C998 B0D09822 C7D7A8B4 59B33D17 2EB40D81 B7BD5C3B C0BA6CAD EDB88320 9ABFB3B6 03B6E20C 74B1D29A EAD54739 9DD277AF 04DB2615 73DC1683 E3630B12 94643B84 0D6D6A3E 7A6A5AA8 E40ECF0B 9309FF9D 0A00AE27 7D079EB1 F00F9344 8708A3D2 1E01F268 6906C2FE F762575D 806567CB 196C3671 6E6B06E7 FED41B76 89D32BE0 10DA7A5A 67DD4ACC F9B9DF6F 8EBEEFF9 17B7BE43 60B08ED5 D6D6A3E8 A1D1937E 38D8C2C4 4FDFF252 D1BB67F1 A6BC5767 3FB506DD 48B2364B D80D2BDA AF0A1B4C 36034AF6 41047A60 DF60EFC3 A867DF55 316E8EEF 4669BE79 CB61B38C BC66831A 256FD2A0 5268E236 CC0C7795 BB0B4703 220216B9 5505262F C5BA3BBE B2BD0B28 2BB45A92 5CB36A04 C2D7FFA7 B5D0CF31 2CD99E8B 5BDEAE1D 9B64C2B0 EC63F226 756AA39C 026D930A 9C0906A9 EB0E363F 72076785 05005713 95BF4A82 E2B87A14 7BB12BAE 0CB61B38 92D28E9B E5D5BE0D 7CDCEFB7 0BDBDF21 86D3D2D4 F1D4E242 68DDB3F8 1FDA836E 81BE16CD F6B9265B 6FB077E1 18B74777 88085AE6 FF0F6A70 66063BCA 11010B5C 8F659EFF F862AE69 616BFFD3 166CCF45 A00AE278 D70DD2EE 4E048354 3903B3C2 A7672661 D06016F7 4969474D 3E6E77DB AED16A4A D9D65ADC 40DF0B66 37D83BF0 A9BCAE53 DEBB9EC5 47B2CF7F 30B5FFE9 BDBDF21C CABAC28A 53B39330 24B4A3A6 BAD03605 CDD70693 54DE5729 23D967BF B3667A2E C4614AB8 5D681B02 2A6F2B94 B40BBE37 C30C8EA1 5A05DF1B 2D02EF8D";
-
- var crc = 0;
- var x = 0;
- var y = 0;
-
- crc = crc ^ (-1);
- for (var i = 0, iTop = str.length; i < iTop; i++) {
- y = (crc ^ str.charCodeAt(i)) & 0xFF;
- x = "0x" + table.substr(y * 9, 8);
- crc = (crc >>> 8) ^ x;
- }
-
- return crc ^ (-1);
- };
-
- php.date = function (format, timestamp) {
- // Format a local date/time
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/date
- // + original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com)
- // + parts by: Peter-Paul Koch (http://www.quirksmode.org/js/beat.html)
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: MeEtc (http://yass.meetcweb.com)
- // + improved by: Brad Touesnard
- // + improved by: Tim Wiel
- // + improved by: Bryan Elliott
- //
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // + improved by: David Randall
- // + input by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // + improved by: Theriault
- // + derived from: gettimeofday
- // + input by: majak
- // + bugfixed by: majak
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + input by: Alex
- // + bugfixed by: Brett Zamir (http://brett-zamir.me)
- // + improved by: Theriault
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // + improved by: Theriault
- // + improved by: Thomas Beaucourt (http://www.webapp.fr)
- // + improved by: JT
- // + improved by: Theriault
- // + improved by: Rafał Kukawski (http://blog.kukawski.pl)
- // % note 1: Uses global: php_js to store the default timezone
- // % note 2: Although the function potentially allows timezone info (see notes), it currently does not set
- // % note 2: per a timezone specified by date_default_timezone_set(). Implementers might use
- // % note 2: this.php_js.currentTimezoneOffset and this.php_js.currentTimezoneDST set by that function
- // % note 2: in order to adjust the dates in this function (or our other date functions!) accordingly
- // * example 1: \php.date('H:m:s \\m \\i\\s \\m\\o\\n\\t\\h', 1062402400);
- // * returns 1: '09:09:40 m is month'
- // * example 2: \php.date('F j, Y, g:i a', 1062462400);
- // * returns 2: 'September 2, 2003, 2:26 am'
- // * example 3: \php.date('Y W o', 1062462400);
- // * returns 3: '2003 36 2003'
- // * example 4: x = date('Y m d', (new Date()).getTime()/1000);
- // * example 4: (x+'').length == 10 // 2009 01 09
- // * returns 4: true
- // * example 5: \php.date('W', 1104534000);
- // * returns 5: '53'
- // * example 6: \php.date('B t', 1104534000);
- // * returns 6: '999 31'
- // * example 7: \php.date('W U', 1293750000.82); // 2010-12-31
- // * returns 7: '52 1293750000'
- // * example 8: \php.date('W', 1293836400); // 2011-01-01
- // * returns 8: '52'
- // * example 9: \php.date('W Y-m-d', 1293974054); // 2011-01-02
- // * returns 9: '52 2011-01-02'
- var that = this,
- jsdate, f, formatChr = /\\?([a-z])/gi,
- formatChrCb,
- // Keep this here (works, but for code commented-out
- // below for file size reasons)
- //, tal= [],
- _pad = function (n, c) {
- if ((n = n + "").length < c) {
- return new Array((++c) - n.length).join("0") + n;
- } else {
- return n;
- }
- },
- txt_words = ["Sun", "Mon", "Tues", "Wednes", "Thurs", "Fri", "Satur", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
- txt_ordin = {
- 1: "st",
- 2: "nd",
- 3: "rd",
- 21: "st",
- 22: "nd",
- 23: "rd",
- 31: "st"
- };
- formatChrCb = function (t, s) {
- return f[t] ? f[t]() : s;
- };
- f = {
- // Day
- d: function () { // Day of month w/leading 0; 01..31
- return _pad(f.j(), 2);
- },
- D: function () { // Shorthand day name; Mon...Sun
- return f.l().slice(0, 3);
- },
- j: function () { // Day of month; 1..31
- return jsdate.getDate();
- },
- l: function () { // Full day name; Monday...Sunday
- return txt_words[f.w()] + 'day';
- },
- N: function () { // ISO-8601 day of week; 1[Mon]..7[Sun]
- return f.w() || 7;
- },
- S: function () { // Ordinal suffix for day of month; st, nd, rd, th
- return txt_ordin[f.j()] || 'th';
- },
- w: function () { // Day of week; 0[Sun]..6[Sat]
- return jsdate.getDay();
- },
- z: function () { // Day of year; 0..365
- var a = new Date(f.Y(), f.n() - 1, f.j()),
- b = new Date(f.Y(), 0, 1);
- return Math.round((a - b) / 864e5) + 1;
- },
-
- // Week
- W: function () { // ISO-8601 week number
- var a = new Date(f.Y(), f.n() - 1, f.j() - f.N() + 3),
- b = new Date(a.getFullYear(), 0, 4);
- return 1 + Math.round((a - b) / 864e5 / 7);
- },
-
- // Month
- F: function () { // Full month name; January...December
- return txt_words[6 + f.n()];
- },
- m: function () { // Month w/leading 0; 01...12
- return _pad(f.n(), 2);
- },
- M: function () { // Shorthand month name; Jan...Dec
- return f.F().slice(0, 3);
- },
- n: function () { // Month; 1...12
- return jsdate.getMonth() + 1;
- },
- t: function () { // Days in month; 28...31
- return (new Date(f.Y(), f.n(), 0)).getDate();
- },
-
- // Year
- L: function () { // Is leap year?; 0 or 1
- return new Date(f.Y(), 1, 29).getMonth() === 1 | 0;
- },
- o: function () { // ISO-8601 year
- var n = f.n(),
- W = f.W(),
- Y = f.Y();
- return Y + (n === 12 && W < 9 ? -1 : n === 1 && W > 9);
- },
- Y: function () { // Full year; e.g. 1980...2010
- return jsdate.getFullYear();
- },
- y: function () { // Last two digits of year; 00...99
- return (f.Y() + "").slice(-2);
- },
-
- // Time
- a: function () { // am or pm
- return jsdate.getHours() > 11 ? "pm" : "am";
- },
- A: function () { // AM or PM
- return f.a().toUpperCase();
- },
- B: function () { // Swatch Internet time; 000..999
- var H = jsdate.getUTCHours() * 36e2,
- // Hours
- i = jsdate.getUTCMinutes() * 60,
- // Minutes
- s = jsdate.getUTCSeconds(); // Seconds
- return _pad(Math.floor((H + i + s + 36e2) / 86.4) % 1e3, 3);
- },
- g: function () { // 12-Hours; 1..12
- return f.G() % 12 || 12;
- },
- G: function () { // 24-Hours; 0..23
- return jsdate.getHours();
- },
- h: function () { // 12-Hours w/leading 0; 01..12
- return _pad(f.g(), 2);
- },
- H: function () { // 24-Hours w/leading 0; 00..23
- return _pad(f.G(), 2);
- },
- i: function () { // Minutes w/leading 0; 00..59
- return _pad(jsdate.getMinutes(), 2);
- },
- s: function () { // Seconds w/leading 0; 00..59
- return _pad(jsdate.getSeconds(), 2);
- },
- u: function () { // Microseconds; 000000-999000
- return _pad(jsdate.getMilliseconds() * 1000, 6);
- },
-
- // Timezone
- e: function () { // Timezone identifier; e.g. Atlantic/Azores, ...
- // The following works, but requires inclusion of the very large
- // timezone_abbreviations_list() function.
- /* return this.date_default_timezone_get();
- */
- throw 'Not supported (see source code of date() for timezone on how to add support)';
- },
- I: function () { // DST observed?; 0 or 1
- // Compares Jan 1 minus Jan 1 UTC to Jul 1 minus Jul 1 UTC.
- // If they are not equal, then DST is observed.
- var a = new Date(f.Y(), 0),
- // Jan 1
- c = Date.UTC(f.Y(), 0),
- // Jan 1 UTC
- b = new Date(f.Y(), 6),
- // Jul 1
- d = Date.UTC(f.Y(), 6); // Jul 1 UTC
- return 0 + ((a - c) !== (b - d));
- },
- O: function () { // Difference to GMT in hour format; e.g. +0200
- var a = jsdate.getTimezoneOffset();
- return (a > 0 ? "-" : "+") + _pad(Math.abs(a / 60 * 100), 4);
- },
- P: function () { // Difference to GMT w/colon; e.g. +02:00
- var O = f.O();
- return (O.substr(0, 3) + ":" + O.substr(3, 2));
- },
- T: function () { // Timezone abbreviation; e.g. EST, MDT, ...
- // The following works, but requires inclusion of the very
- // large timezone_abbreviations_list() function.
- /* var abbr = '', i = 0, os = 0, default = 0;
- if (!tal.length) {
- tal = that.timezone_abbreviations_list();
- }
- if (that.php_js && that.php_js.default_timezone) {
- default = that.php_js.default_timezone;
- for (abbr in tal) {
- for (i=0; i < tal[abbr].length; i++) {
- if (tal[abbr][i].timezone_id === default) {
- return abbr.toUpperCase();
- }
- }
- }
- }
- for (abbr in tal) {
- for (i = 0; i < tal[abbr].length; i++) {
- os = -jsdate.getTimezoneOffset() * 60;
- if (tal[abbr][i].offset === os) {
- return abbr.toUpperCase();
- }
- }
- }
- */
- return 'UTC';
- },
- Z: function () { // Timezone offset in seconds (-43200...50400)
- return -jsdate.getTimezoneOffset() * 60;
- },
-
- // Full Date/Time
- c: function () { // ISO-8601 date.
- return 'Y-m-d\\Th:i:sP'.replace(formatChr, formatChrCb);
- },
- r: function () { // RFC 2822
- return 'D, d M Y H:i:s O'.replace(formatChr, formatChrCb);
- },
- U: function () { // Seconds since UNIX epoch
- return jsdate.getTime() / 1000 | 0;
- }
- };
- this.date = function (format, timestamp) {
- that = this;
- jsdate = ((typeof timestamp === 'undefined') ? new Date() : // Not provided
- (timestamp instanceof Date) ? new Date(timestamp) : // JS Date()
- new Date(timestamp * 1000) // UNIX timestamp (auto-convert to int)
- );
- return format.replace(formatChr, formatChrCb);
- };
- return this.date(format, timestamp);
- };
-
- php.dirname = function (path) {
- // Returns the directory name component of the path
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/dirname
- // + original by: Ozh
- // + improved by: XoraX (http://www.xorax.info)
- // * example 1: \php.dirname('/etc/passwd');
- // * returns 1: '/etc'
- // * example 2: \php.dirname('c:/Temp/x');
- // * returns 2: 'c:/Temp'
- // * example 3: \php.dirname('/dir/test/');
- // * returns 3: '/dir'
- return path.replace(/\\/g, '/').replace(/\/[^\/]*\/?$/, '');
- };
-
- php.empty = function (mixed_var) {
- // !No description available for empty. @php.js developers: Please update the function summary text file.
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/empty
- // + original by: Philippe Baumann
- // + input by: Onno Marsman
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + input by: LH
- // + improved by: Onno Marsman
- // + improved by: Francesco
- // + improved by: Marc Jansen
- // + input by: Stoyan Kyosev (http://www.svest.org/)
- // * example 1: \php.empty(null);
- // * returns 1: true
- // * example 2: \php.empty(undefined);
- // * returns 2: true
- // * example 3: \php.empty([]);
- // * returns 3: true
- // * example 4: \php.empty({});
- // * returns 4: true
- // * example 5: \php.empty({'aFunc' : function () { alert('humpty'); } });
- // * returns 5: false
- var key;
-
- if (mixed_var === "" || mixed_var === 0 || mixed_var === "0" || mixed_var === null || mixed_var === false || typeof mixed_var === 'undefined') {
- return true;
- }
-
- if (typeof mixed_var == 'object') {
- for (key in mixed_var) {
- return false;
- }
- return true;
- }
-
- return false;
- };
-
- php.end = function (arr) {
- // Advances array argument's internal pointer to the last element and return it
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/end
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfixed by: Legaev Andrey
- // + revised by: J A R
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + restored by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + revised by: Brett Zamir (http://brett-zamir.me)
- // % note 1: Uses global: php_js to store the array pointer
- // * example 1: \php.end({0: 'Kevin', 1: 'van', 2: 'Zonneveld'});
- // * returns 1: 'Zonneveld'
- // * example 2: \php.end(['Kevin', 'van', 'Zonneveld']);
- // * returns 2: 'Zonneveld'
- // BEGIN REDUNDANT
- this.php_js = this.php_js || {};
- this.php_js.pointers = this.php_js.pointers || [];
- var indexOf = function (value) {
- for (var i = 0, length = this.length; i < length; i++) {
- if (this[i] === value) {
- return i;
- }
- }
- return -1;
- };
- // END REDUNDANT
- var pointers = this.php_js.pointers;
- if (!pointers.indexOf) {
- pointers.indexOf = indexOf;
- }
- if (pointers.indexOf(arr) === -1) {
- pointers.push(arr, 0);
- }
- var arrpos = pointers.indexOf(arr);
- if (!(arr instanceof Array)) {
- var ct = 0;
- for (var k in arr) {
- ct++;
- var val = arr[k];
- }
- if (ct === 0) {
- return false; // Empty
- }
- pointers[arrpos + 1] = ct - 1;
- return val;
- }
- if (arr.length === 0) {
- return false;
- }
- pointers[arrpos + 1] = arr.length - 1;
- return arr[pointers[arrpos + 1]];
- };
-
- php.extract = function (arr, type, prefix) {
- // Imports variables into symbol table from an array
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/extract
- // + original by: Brett Zamir (http://brett-zamir.me)
- // % note 1: Only works by extracting into global context (whether called in the global scope or
- // % note 1: within a function); also, the EXTR_REFS flag I believe can't be made to work
- // * example 1: \php.size = 'large';
- // * example 1: \php.var_array = {'color' : 'blue', 'size' : 'medium', 'shape' : 'sphere'};
- // * example 1: \php.extract(var_array, 'EXTR_PREFIX_SAME', 'wddx');
- // * example 1: \php.color+'-'+size+'-'+shape+'-'+wddx_size;
- // * returns 1: 'blue-large-sphere-medium'
- if (arr instanceof Array && (type !== 'EXTR_PREFIX_ALL' && type !== 'EXTR_PREFIX_INVALID')) {
- return 0;
- }
- var targetObj = this.window;
- if (this.php_js && this.php_js.ini && this.php_js.ini['phpjs.extractTargetObj'] && this.php_js.ini['phpjs.extractTargetObj'].local_value) { // Allow designated object to be used instead of window
- targetObj = this.php_js.ini['phpjs.extractTargetObj'].local_value;
- }
- var chng = 0;
-
- for (var i in arr) {
- var validIdent = /^[_a-zA-Z$][\w|$]*$/; // TODO: Refine regexp to allow JS 1.5+ Unicode identifiers
- var prefixed = prefix + '_' + i;
- try {
- switch (type) {
- case 'EXTR_PREFIX_SAME' || 2:
- if (targetObj[i] !== undefined) {
- if (prefixed.match(validIdent) !== null) {
- targetObj[prefixed] = arr[i];
- ++chng;
- }
- } else {
- targetObj[i] = arr[i];
- ++chng;
- }
- break;
- case 'EXTR_SKIP' || 1:
- if (targetObj[i] === undefined) {
- targetObj[i] = arr[i];
- ++chng;
- }
- break;
- case 'EXTR_PREFIX_ALL' || 3:
- if (prefixed.match(validIdent) !== null) {
- targetObj[prefixed] = arr[i];
- ++chng;
- }
- break;
- case 'EXTR_PREFIX_INVALID' || 4:
- if (i.match(validIdent) !== null) {
- if (prefixed.match(validIdent) !== null) {
- targetObj[prefixed] = arr[i];
- ++chng;
- }
- } else {
- targetObj[i] = arr[i];
- ++chng;
- }
- break;
- case 'EXTR_IF_EXISTS' || 6:
- if (targetObj[i] !== undefined) {
- targetObj[i] = arr[i];
- ++chng;
- }
- break;
- case 'EXTR_PREFIX_IF_EXISTS' || 5:
- if (targetObj[i] !== undefined && prefixed.match(validIdent) !== null) {
- targetObj[prefixed] = arr[i];
- ++chng;
- }
- break;
- case 'EXTR_REFS' || 256:
- throw 'The EXTR_REFS type will not work in JavaScript';
- case 'EXTR_OVERWRITE' || 0:
- // Fall-through
- default:
- targetObj[i] = arr[i];
- ++chng;
- break;
- }
- } catch (e) { // Just won't increment for problem assignments
- }
- }
- return chng;
- };
-
- php.floor = function (value) {
- // Returns the next lowest integer value from the number
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/floor
- // + original by: Onno Marsman
- // * example 1: \php.floor(8723321.4);
- // * returns 1: 8723321
- return Math.floor(value);
- };
-
- php.get_class = function (obj) {
- // Retrieves the class name
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/get_class
- // + original by: Ates Goral (http://magnetiq.com)
- // + improved by: David James
- // * example 1: \php.get_class(new (function MyClass() {}));
- // * returns 1: "MyClass"
- // * example 2: \php.get_class({});
- // * returns 2: "Object"
- // * example 3: \php.get_class([]);
- // * returns 3: false
- // * example 4: \php.get_class(42);
- // * returns 4: false
- // * example 5: \php.get_class(window);
- // * returns 5: false
- // * example 6: \php.get_class(function MyFunction() {});
- // * returns 6: false
- if (obj instanceof Object && !(obj instanceof Array) && !(obj instanceof Function) && obj.constructor && obj != this.window) {
- var arr = obj.constructor.toString().match(/function\s*(\w+)/);
-
- if (arr && arr.length == 2) {
- return arr[1];
- }
- }
-
- return false;
- };
-
- php.get_html_translation_table = function (table, quote_style) {
- // Returns the internal translation table used by htmlspecialchars and htmlentities
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/get_html_translation_table
- // + original by: Philip Peterson
- // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfixed by: noname
- // + bugfixed by: Alex
- // + bugfixed by: Marco
- // + bugfixed by: madipta
- // + improved by: KELAN
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: Brett Zamir (http://brett-zamir.me)
- // + input by: Frank Forte
- // + bugfixed by: T.Wild
- // + input by: Ratheous
- // % note: It has been decided that we're not going to add global
- // % note: dependencies to php.js, meaning the constants are not
- // % note: real constants, but strings instead. Integers are also supported if someone
- // % note: chooses to create the constants themselves.
- // * example 1: \php.get_html_translation_table('HTML_SPECIALCHARS');
- // * returns 1: {'"': '"', '&': '&', '<': '<', '>': '>'}
- var entities = {},
- hash_map = {},
- decimal = 0,
- symbol = '';
- var constMappingTable = {},
- constMappingQuoteStyle = {};
- var useTable = {},
- useQuoteStyle = {};
-
- // Translate arguments
- constMappingTable[0] = 'HTML_SPECIALCHARS';
- constMappingTable[1] = 'HTML_ENTITIES';
- constMappingQuoteStyle[0] = 'ENT_NOQUOTES';
- constMappingQuoteStyle[2] = 'ENT_COMPAT';
- constMappingQuoteStyle[3] = 'ENT_QUOTES';
-
- useTable = !isNaN(table) ? constMappingTable[table] : table ? table.toUpperCase() : 'HTML_SPECIALCHARS';
- useQuoteStyle = !isNaN(quote_style) ? constMappingQuoteStyle[quote_style] : quote_style ? quote_style.toUpperCase() : 'ENT_COMPAT';
-
- if (useTable !== 'HTML_SPECIALCHARS' && useTable !== 'HTML_ENTITIES') {
- throw new Error("Table: " + useTable + ' not supported');
- // return false;
- }
-
- entities['38'] = '&';
- if (useTable === 'HTML_ENTITIES') {
- entities['160'] = ' ';
- entities['161'] = '¡';
- entities['162'] = '¢';
- entities['163'] = '£';
- entities['164'] = '¤';
- entities['165'] = '¥';
- entities['166'] = '¦';
- entities['167'] = '§';
- entities['168'] = '¨';
- entities['169'] = '©';
- entities['170'] = 'ª';
- entities['171'] = '«';
- entities['172'] = '¬';
- entities['173'] = '­';
- entities['174'] = '®';
- entities['175'] = '¯';
- entities['176'] = '°';
- entities['177'] = '±';
- entities['178'] = '²';
- entities['179'] = '³';
- entities['180'] = '´';
- entities['181'] = 'µ';
- entities['182'] = '¶';
- entities['183'] = '·';
- entities['184'] = '¸';
- entities['185'] = '¹';
- entities['186'] = 'º';
- entities['187'] = '»';
- entities['188'] = '¼';
- entities['189'] = '½';
- entities['190'] = '¾';
- entities['191'] = '¿';
- entities['192'] = 'À';
- entities['193'] = 'Á';
- entities['194'] = 'Â';
- entities['195'] = 'Ã';
- entities['196'] = 'Ä';
- entities['197'] = 'Å';
- entities['198'] = 'Æ';
- entities['199'] = 'Ç';
- entities['200'] = 'È';
- entities['201'] = 'É';
- entities['202'] = 'Ê';
- entities['203'] = 'Ë';
- entities['204'] = 'Ì';
- entities['205'] = 'Í';
- entities['206'] = 'Î';
- entities['207'] = 'Ï';
- entities['208'] = 'Ð';
- entities['209'] = 'Ñ';
- entities['210'] = 'Ò';
- entities['211'] = 'Ó';
- entities['212'] = 'Ô';
- entities['213'] = 'Õ';
- entities['214'] = 'Ö';
- entities['215'] = '×';
- entities['216'] = 'Ø';
- entities['217'] = 'Ù';
- entities['218'] = 'Ú';
- entities['219'] = 'Û';
- entities['220'] = 'Ü';
- entities['221'] = 'Ý';
- entities['222'] = 'Þ';
- entities['223'] = 'ß';
- entities['224'] = 'à';
- entities['225'] = 'á';
- entities['226'] = 'â';
- entities['227'] = 'ã';
- entities['228'] = 'ä';
- entities['229'] = 'å';
- entities['230'] = 'æ';
- entities['231'] = 'ç';
- entities['232'] = 'è';
- entities['233'] = 'é';
- entities['234'] = 'ê';
- entities['235'] = 'ë';
- entities['236'] = 'ì';
- entities['237'] = 'í';
- entities['238'] = 'î';
- entities['239'] = 'ï';
- entities['240'] = 'ð';
- entities['241'] = 'ñ';
- entities['242'] = 'ò';
- entities['243'] = 'ó';
- entities['244'] = 'ô';
- entities['245'] = 'õ';
- entities['246'] = 'ö';
- entities['247'] = '÷';
- entities['248'] = 'ø';
- entities['249'] = 'ù';
- entities['250'] = 'ú';
- entities['251'] = 'û';
- entities['252'] = 'ü';
- entities['253'] = 'ý';
- entities['254'] = 'þ';
- entities['255'] = 'ÿ';
- }
-
- if (useQuoteStyle !== 'ENT_NOQUOTES') {
- entities['34'] = '"';
- }
- if (useQuoteStyle === 'ENT_QUOTES') {
- entities['39'] = ''';
- }
- entities['60'] = '<';
- entities['62'] = '>';
-
-
- // ascii decimals to real symbols
- for (decimal in entities) {
- symbol = String.fromCharCode(decimal);
- hash_map[symbol] = entities[decimal];
- }
-
- return hash_map;
- };
-
- php.gettype = function (mixed_var) {
- // Returns the type of the variable
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/gettype
- // + original by: Paulo Freitas
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Douglas Crockford (http://javascript.crockford.com)
- // + input by: KELAN
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // - depends on: is_float
- // % note 1: 1.0 is simplified to 1 before it can be accessed by the function, this makes
- // % note 1: it different from the PHP implementation. We can't fix this unfortunately.
- // * example 1: \php.gettype(1);
- // * returns 1: 'integer'
- // * example 2: \php.gettype(undefined);
- // * returns 2: 'undefined'
- // * example 3: \php.gettype({0: 'Kevin van Zonneveld'});
- // * returns 3: 'array'
- // * example 4: \php.gettype('foo');
- // * returns 4: 'string'
- // * example 5: \php.gettype({0: function () {return false;}});
- // * returns 5: 'array'
- var s = typeof mixed_var,
- name;
- var getFuncName = function (fn) {
- var name = (/\W*function\s+([\w\$]+)\s*\(/).exec(fn);
- if (!name) {
- return '(Anonymous)';
- }
- return name[1];
- };
- if (s === 'object') {
- if (mixed_var !== null) { // From: http://javascript.crockford.com/remedial.html
- if (typeof mixed_var.length === 'number' && !(mixed_var.propertyIsEnumerable('length')) && typeof mixed_var.splice === 'function') {
- s = 'array';
- } else if (mixed_var.constructor && getFuncName(mixed_var.constructor)) {
- name = getFuncName(mixed_var.constructor);
- if (name === 'Date') {
- s = 'date'; // not in PHP
- } else if (name === 'RegExp') {
- s = 'regexp'; // not in PHP
- } else if (name === 'PHPJS_Resource') { // Check against our own resource constructor
- s = 'resource';
- }
- }
- } else {
- s = 'null';
- }
- } else if (s === 'number') {
- s = this.is_float(mixed_var) ? 'double' : 'integer';
- }
- return s;
- };
-
- php.html_entity_decode = function (string, quote_style) {
- // Convert all HTML entities to their applicable characters
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/html_entity_decode
- // + original by: john (http://www.jd-tech.net)
- // + input by: ger
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfixed by: Onno Marsman
- // + improved by: marc andreu
- // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + input by: Ratheous
- // + bugfixed by: Brett Zamir (http://brett-zamir.me)
- // + input by: Nick Kolosov (http://sammy.ru)
- // + bugfixed by: Fox
- // - depends on: get_html_translation_table
- // * example 1: \php.html_entity_decode('Kevin & van Zonneveld');
- // * returns 1: 'Kevin & van Zonneveld'
- // * example 2: \php.html_entity_decode('&lt;');
- // * returns 2: '<'
- var hash_map = {},
- symbol = '',
- tmp_str = '',
- entity = '';
- tmp_str = string.toString();
-
- if (false === (hash_map = this.get_html_translation_table('HTML_ENTITIES', quote_style))) {
- return false;
- }
-
- // fix & problem
- // http://phpjs.org/functions/get_html_translation_table:416#comment_97660
- delete(hash_map['&']);
- hash_map['&'] = '&';
-
- for (symbol in hash_map) {
- entity = hash_map[symbol];
- tmp_str = tmp_str.split(entity).join(symbol);
- }
- tmp_str = tmp_str.split(''').join("'");
-
- return tmp_str;
- };
-
- php.htmlentities = function (string, quote_style) {
- // Convert all applicable characters to HTML entities
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/htmlentities
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: nobbler
- // + tweaked by: Jack
- // + bugfixed by: Onno Marsman
- // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfixed by: Brett Zamir (http://brett-zamir.me)
- // + input by: Ratheous
- // - depends on: get_html_translation_table
- // * example 1: \php.htmlentities('Kevin & van Zonneveld');
- // * returns 1: 'Kevin & van Zonneveld'
- // * example 2: \php.htmlentities("foo'bar","ENT_QUOTES");
- // * returns 2: 'foo'bar'
- var hash_map = {},
- symbol = '',
- tmp_str = '',
- entity = '';
- tmp_str = string.toString();
-
- if (false === (hash_map = this.get_html_translation_table('HTML_ENTITIES', quote_style))) {
- return false;
- }
- hash_map["'"] = ''';
- for (symbol in hash_map) {
- entity = hash_map[symbol];
- tmp_str = tmp_str.split(symbol).join(entity);
- }
-
- return tmp_str;
- };
-
- php.htmlspecialchars = function (string, quote_style, charset, double_encode) {
- // Convert special characters to HTML entities
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/htmlspecialchars
- // + original by: Mirek Slugen
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfixed by: Nathan
- // + bugfixed by: Arno
- // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfixed by: Brett Zamir (http://brett-zamir.me)
- // + input by: Ratheous
- // + input by: Mailfaker (http://www.weedem.fr/)
- // + reimplemented by: Brett Zamir (http://brett-zamir.me)
- // + input by: felix
- // + bugfixed by: Brett Zamir (http://brett-zamir.me)
- // % note 1: charset argument not supported
- // * example 1: \php.htmlspecialchars("<a href='test'>Test</a>", 'ENT_QUOTES');
- // * returns 1: '<a href='test'>Test</a>'
- // * example 2: \php.htmlspecialchars("ab\"c'd", ['ENT_NOQUOTES', 'ENT_QUOTES']);
- // * returns 2: 'ab"c'd'
- // * example 3: \php.htmlspecialchars("my "&entity;" is still here", null, null, false);
- // * returns 3: 'my "&entity;" is still here'
- var optTemp = 0,
- i = 0,
- noquotes = false;
- if (typeof quote_style === 'undefined' || quote_style === null) {
- quote_style = 2;
- }
- if (string === null) {
- string = "";
- }
- string = string.toString();
- if (double_encode !== false) { // Put this first to avoid double-encoding
- string = string.replace(/&/g, '&');
- }
- string = string.replace(/</g, '<').replace(/>/g, '>');
-
- var OPTS = {
- 'ENT_NOQUOTES': 0,
- 'ENT_HTML_QUOTE_SINGLE': 1,
- 'ENT_HTML_QUOTE_DOUBLE': 2,
- 'ENT_COMPAT': 2,
- 'ENT_QUOTES': 3,
- 'ENT_IGNORE': 4
- };
- if (quote_style === 0) {
- noquotes = true;
- }
- if (typeof quote_style !== 'number') { // Allow for a single string or an array of string flags
- quote_style = [].concat(quote_style);
- for (i = 0; i < quote_style.length; i++) {
- // Resolve string input to bitwise e.g. 'PATHINFO_EXTENSION' becomes 4
- if (OPTS[quote_style[i]] === 0) {
- noquotes = true;
- } else if (OPTS[quote_style[i]]) {
- optTemp = optTemp | OPTS[quote_style[i]];
- }
- }
- quote_style = optTemp;
- }
- if (quote_style & OPTS.ENT_HTML_QUOTE_SINGLE) {
- string = string.replace(/'/g, ''');
- }
- if (!noquotes) {
- string = string.replace(/"/g, '"');
- }
-
- return string;
- };
-
- php.htmlspecialchars_decode = function (string, quote_style) {
- // Convert special HTML entities back to characters
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/htmlspecialchars_decode
- // + original by: Mirek Slugen
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfixed by: Mateusz "loonquawl" Zalega
- // + input by: ReverseSyntax
- // + input by: Slawomir Kaniecki
- // + input by: Scott Cariss
- // + input by: Francois
- // + bugfixed by: Onno Marsman
- // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfixed by: Brett Zamir (http://brett-zamir.me)
- // + input by: Ratheous
- // + input by: Mailfaker (http://www.weedem.fr/)
- // + reimplemented by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: Brett Zamir (http://brett-zamir.me)
- // * example 1: \php.htmlspecialchars_decode("<p>this -> "</p>", 'ENT_NOQUOTES');
- // * returns 1: '<p>this -> "</p>'
- // * example 2: \php.htmlspecialchars_decode("&quot;");
- // * returns 2: '"'
- var optTemp = 0,
- i = 0,
- noquotes = false;
- if (typeof quote_style === 'undefined') {
- quote_style = 2;
- }
- string = string.toString().replace(/</g, '<').replace(/>/g, '>');
- var OPTS = {
- 'ENT_NOQUOTES': 0,
- 'ENT_HTML_QUOTE_SINGLE': 1,
- 'ENT_HTML_QUOTE_DOUBLE': 2,
- 'ENT_COMPAT': 2,
- 'ENT_QUOTES': 3,
- 'ENT_IGNORE': 4
- };
- if (quote_style === 0) {
- noquotes = true;
- }
- if (typeof quote_style !== 'number') { // Allow for a single string or an array of string flags
- quote_style = [].concat(quote_style);
- for (i = 0; i < quote_style.length; i++) {
- // Resolve string input to bitwise e.g. 'PATHINFO_EXTENSION' becomes 4
- if (OPTS[quote_style[i]] === 0) {
- noquotes = true;
- } else if (OPTS[quote_style[i]]) {
- optTemp = optTemp | OPTS[quote_style[i]];
- }
- }
- quote_style = optTemp;
- }
- if (quote_style & OPTS.ENT_HTML_QUOTE_SINGLE) {
- string = string.replace(/�*39;/g, "'"); // PHP doesn't currently escape if more than one 0, but it should
- // string = string.replace(/'|�*27;/g, "'"); // This would also be useful here, but not a part of PHP
- }
- if (!noquotes) {
- string = string.replace(/"/g, '"');
- }
- // Put this in last place to avoid escape being double-decoded
- string = string.replace(/&/g, '&');
-
- return string;
- };
-
- php.http_build_query = function (formdata, numeric_prefix, arg_separator) {
- // Generates a form-encoded query string from an associative array or object.
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/http_build_query
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Legaev Andrey
- // + improved by: Michael White (http://getsprink.com)
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // + revised by: stag019
- // + input by: Dreamer
- // + bugfixed by: Brett Zamir (http://brett-zamir.me)
- // - depends on: urlencode
- // * example 1: \php.http_build_query({foo: 'bar', php: 'hypertext processor', baz: 'boom', cow: 'milk'}, '', '&');
- // * returns 1: 'foo=bar&php=hypertext+processor&baz=boom&cow=milk'
- // * example 2: \php.http_build_query({'php': 'hypertext processor', 0: 'foo', 1: 'bar', 2: 'baz', 3: 'boom', 'cow': 'milk'}, 'myvar_');
- // * returns 2: 'php=hypertext+processor&myvar_0=foo&myvar_1=bar&myvar_2=baz&myvar_3=boom&cow=milk'
- var value, key, tmp = [],
- that = this;
-
- var _http_build_query_helper = function (key, val, arg_separator) {
- var k, tmp = [];
- if (val === true) {
- val = "1";
- } else if (val === false) {
- val = "0";
- }
- if (val !== null && typeof(val) === "object") {
- for (k in val) {
- if (val[k] !== null) {
- tmp.push(_http_build_query_helper(key + "[" + k + "]", val[k], arg_separator));
- }
- }
- return tmp.join(arg_separator);
- } else if (typeof(val) !== "function") {
- return that.urlencode(key) + "=" + that.urlencode(val);
- } else {
- throw new Error('There was an error processing for http_build_query().');
- }
- };
-
- if (!arg_separator) {
- arg_separator = "&";
- }
- for (key in formdata) {
- value = formdata[key];
- if (numeric_prefix && !isNaN(key)) {
- key = String(numeric_prefix) + key;
- }
- tmp.push(_http_build_query_helper(key, value, arg_separator));
- }
-
- return tmp.join(arg_separator);
- };
-
- php.in_array = function (needle, haystack, argStrict) {
- // Checks if the given value exists in the array
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/in_array
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: vlado houba
- // + input by: Billy
- // + bugfixed by: Brett Zamir (http://brett-zamir.me)
- // * example 1: \php.in_array('van', ['Kevin', 'van', 'Zonneveld']);
- // * returns 1: true
- // * example 2: \php.in_array('vlado', {0: 'Kevin', vlado: 'van', 1: 'Zonneveld'});
- // * returns 2: false
- // * example 3: \php.in_array(1, ['1', '2', '3']);
- // * returns 3: true
- // * example 3: \php.in_array(1, ['1', '2', '3'], false);
- // * returns 3: true
- // * example 4: \php.in_array(1, ['1', '2', '3'], true);
- // * returns 4: false
- var key = '',
- strict = !! argStrict;
-
- if (strict) {
- for (key in haystack) {
- if (haystack[key] === needle) {
- return true;
- }
- }
- } else {
- for (key in haystack) {
- if (haystack[key] == needle) {
- return true;
- }
- }
- }
-
- return false;
- };
-
- php.intval = function (mixed_var, base) {
- // Get the integer value of a variable using the optional base for the conversion
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/intval
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: stensi
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + input by: Matteo
- // + bugfixed by: Brett Zamir (http://brett-zamir.me)
- // * example 1: \php.intval('Kevin van Zonneveld');
- // * returns 1: 0
- // * example 2: \php.intval(4.2);
- // * returns 2: 4
- // * example 3: \php.intval(42, 8);
- // * returns 3: 42
- // * example 4: \php.intval('09');
- // * returns 4: 9
- // * example 5: \php.intval('1e', 16);
- // * returns 5: 30
- var tmp;
-
- var type = typeof(mixed_var);
-
- if (type === 'boolean') {
- return (mixed_var) ? 1 : 0;
- } else if (type === 'string') {
- tmp = parseInt(mixed_var, base || 10);
- return (isNaN(tmp) || !isFinite(tmp)) ? 0 : tmp;
- } else if (type === 'number' && isFinite(mixed_var)) {
- return Math.floor(mixed_var);
- } else {
- return 0;
- }
- };
-
- php.is_callable = function (v, syntax_only, callable_name) {
- // Returns true if var is callable.
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/is_callable
- // + original by: Brett Zamir (http://brett-zamir.me)
- // % note 1: The variable callable_name cannot work as a string variable passed by reference as in PHP (since JavaScript does not support passing strings by reference), but instead will take the name of a global variable and set that instead
- // % note 2: When used on an object, depends on a constructor property being kept on the object prototype
- // * example 1: \php.is_callable('is_callable');
- // * returns 1: true
- // * example 2: \php.is_callable('bogusFunction', true);
- // * returns 2:true // gives true because does not do strict checking
- // * example 3: \php.function SomeClass () {}
- // * example 3: SomeClass.prototype.someMethod = function (){};
- // * example 3: \php.var testObj = new SomeClass();
- // * example 3: \php.is_callable([testObj, 'someMethod'], true, 'myVar');
- // * example 3: \php.alert(myVar); // 'SomeClass::someMethod'
- var name = '',
- obj = {},
- method = '';
- var getFuncName = function (fn) {
- var name = (/\W*function\s+([\w\$]+)\s*\(/).exec(fn);
- if (!name) {
- return '(Anonymous)';
- }
- return name[1];
- };
- if (typeof v === 'string') {
- obj = this.window;
- method = v;
- name = v;
- } else if (v instanceof Array && v.length === 2 && typeof v[0] === 'object' && typeof v[1] === 'string') {
- obj = v[0];
- method = v[1];
- name = (obj.constructor && getFuncName(obj.constructor)) + '::' + method;
- } else {
- return false;
- }
- if (syntax_only || typeof obj[method] === 'function') {
- if (callable_name) {
- this.window[callable_name] = name;
- }
- return true;
- }
- return false;
- };
-
- php.is_float = function (mixed_var) {
- // Returns true if variable is float point
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/is_float
- // + original by: Paulo Freitas
- // + bugfixed by: Brett Zamir (http://brett-zamir.me)
- // + improved by: WebDevHobo (http://webdevhobo.blogspot.com/)
- // % note 1: 1.0 is simplified to 1 before it can be accessed by the function, this makes
- // % note 1: it different from the PHP implementation. We can't fix this unfortunately.
- // * example 1: \php.is_float(186.31);
- // * returns 1: true
- if (typeof mixed_var !== 'number') {
- return false;
- }
-
- return !!(mixed_var % 1);
- };
-
- php.is_int = function (mixed_var) {
- // !No description available for is_int. @php.js developers: Please update the function summary text file.
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/is_int
- // + original by: Alex
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + revised by: Matt Bradley
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: WebDevHobo (http://webdevhobo.blogspot.com/)
- // % note 1: 1.0 is simplified to 1 before it can be accessed by the function, this makes
- // % note 1: it different from the PHP implementation. We can't fix this unfortunately.
- // * example 1: \php.is_int(23)
- // * returns 1: true
- // * example 2: \php.is_int('23')
- // * returns 2: false
- // * example 3: \php.is_int(23.5)
- // * returns 3: false
- // * example 4: \php.is_int(true)
- // * returns 4: false
- if (typeof mixed_var !== 'number') {
- return false;
- }
-
- return !(mixed_var % 1);
- };
-
- php.krsort = function (inputArr, sort_flags) {
- // Sort an array by key value in reverse order
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/krsort
- // + original by: GeekFG (http://geekfg.blogspot.com)
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // % note 1: The examples are correct, this is a new way
- // % note 2: This function deviates from PHP in returning a copy of the array instead
- // % note 2: of acting by reference and returning true; this was necessary because
- // % note 2: IE does not allow deleting and re-adding of properties without caching
- // % note 2: of property position; you can set the ini of "phpjs.strictForIn" to true to
- // % note 2: get the PHP behavior, but use this only if you are in an environment
- // % note 2: such as Firefox extensions where for-in iteration order is fixed and true
- // % note 2: property deletion is supported. Note that we intend to implement the PHP
- // % note 2: behavior by default if IE ever does allow it; only gives shallow copy since
- // % note 2: is by reference in PHP anyways
- // % note 3: Since JS objects' keys are always strings, and (the
- // % note 3: default) SORT_REGULAR flag distinguishes by key type,
- // % note 3: if the content is a numeric string, we treat the
- // % note 3: "original type" as numeric.
- // - depends on: i18n_loc_get_default
- // * example 1: \php.data = {d: 'lemon', a: 'orange', b: 'banana', c: 'apple'};
- // * example 1: \php.data = krsort(data);
- // * results 1: {d: 'lemon', c: 'apple', b: 'banana', a: 'orange'}
- // * example 2: \php.ini_set('phpjs.strictForIn', true);
- // * example 2: \php.data = {2: 'van', 3: 'Zonneveld', 1: 'Kevin'};
- // * example 2: \php.krsort(data);
- // * results 2: data == {3: 'Kevin', 2: 'van', 1: 'Zonneveld'}
- // * returns 2: true
- var tmp_arr = {},
- keys = [],
- sorter, i, k, that = this,
- strictForIn = false,
- populateArr = {};
-
- switch (sort_flags) {
- case 'SORT_STRING':
- // compare items as strings
- sorter = function (a, b) {
- return that.strnatcmp(b, a);
- };
- break;
- case 'SORT_LOCALE_STRING':
- // compare items as strings, based on the current locale (set with i18n_loc_set_default() as of PHP6)
- var loc = this.i18n_loc_get_default();
- sorter = this.php_js.i18nLocales[loc].sorting;
- break;
- case 'SORT_NUMERIC':
- // compare items numerically
- sorter = function (a, b) {
- return (b - a);
- };
- break;
- case 'SORT_REGULAR':
- // compare items normally (don't change types)
- default:
- sorter = function (b, a) {
- var aFloat = parseFloat(a),
- bFloat = parseFloat(b),
- aNumeric = aFloat + '' === a,
- bNumeric = bFloat + '' === b;
- if (aNumeric && bNumeric) {
- return aFloat > bFloat ? 1 : aFloat < bFloat ? -1 : 0;
- } else if (aNumeric && !bNumeric) {
- return 1;
- } else if (!aNumeric && bNumeric) {
- return -1;
- }
- return a > b ? 1 : a < b ? -1 : 0;
- };
- break;
- }
-
- // Make a list of key names
- for (k in inputArr) {
- if (inputArr.hasOwnProperty(k)) {
- keys.push(k);
- }
- }
- keys.sort(sorter);
-
- // BEGIN REDUNDANT
- this.php_js = this.php_js || {};
- this.php_js.ini = this.php_js.ini || {};
- // END REDUNDANT
- strictForIn = this.php_js.ini['phpjs.strictForIn'] && this.php_js.ini['phpjs.strictForIn'].local_value && this.php_js.ini['phpjs.strictForIn'].local_value !== 'off';
- populateArr = strictForIn ? inputArr : populateArr;
-
-
- // Rebuild array with sorted key names
- for (i = 0; i < keys.length; i++) {
- k = keys[i];
- tmp_arr[k] = inputArr[k];
- if (strictForIn) {
- delete inputArr[k];
- }
- }
- for (i in tmp_arr) {
- if (tmp_arr.hasOwnProperty(i)) {
- populateArr[i] = tmp_arr[i];
- }
- }
-
- return strictForIn || populateArr;
- };
-
- php.ksort = function (inputArr, sort_flags) {
- // Sort an array by key
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/ksort
- // + original by: GeekFG (http://geekfg.blogspot.com)
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // % note 1: The examples are correct, this is a new way
- // % note 2: This function deviates from PHP in returning a copy of the array instead
- // % note 2: of acting by reference and returning true; this was necessary because
- // % note 2: IE does not allow deleting and re-adding of properties without caching
- // % note 2: of property position; you can set the ini of "phpjs.strictForIn" to true to
- // % note 2: get the PHP behavior, but use this only if you are in an environment
- // % note 2: such as Firefox extensions where for-in iteration order is fixed and true
- // % note 2: property deletion is supported. Note that we intend to implement the PHP
- // % note 2: behavior by default if IE ever does allow it; only gives shallow copy since
- // % note 2: is by reference in PHP anyways
- // % note 3: Since JS objects' keys are always strings, and (the
- // % note 3: default) SORT_REGULAR flag distinguishes by key type,
- // % note 3: if the content is a numeric string, we treat the
- // % note 3: "original type" as numeric.
- // - depends on: i18n_loc_get_default
- // - depends on: strnatcmp
- // * example 1: \php.data = {d: 'lemon', a: 'orange', b: 'banana', c: 'apple'};
- // * example 1: \php.data = ksort(data);
- // * results 1: {a: 'orange', b: 'banana', c: 'apple', d: 'lemon'}
- // * example 2: \php.ini_set('phpjs.strictForIn', true);
- // * example 2: \php.data = {2: 'van', 3: 'Zonneveld', 1: 'Kevin'};
- // * example 2: \php.ksort(data);
- // * results 2: data == {1: 'Kevin', 2: 'van', 3: 'Zonneveld'}
- // * returns 2: true
- var tmp_arr = {},
- keys = [],
- sorter, i, k, that = this,
- strictForIn = false,
- populateArr = {};
-
- switch (sort_flags) {
- case 'SORT_STRING':
- // compare items as strings
- sorter = function (a, b) {
- return that.strnatcmp(a, b);
- };
- break;
- case 'SORT_LOCALE_STRING':
- // compare items as strings, based on the current locale (set with i18n_loc_set_default() as of PHP6)
- var loc = this.i18n_loc_get_default();
- sorter = this.php_js.i18nLocales[loc].sorting;
- break;
- case 'SORT_NUMERIC':
- // compare items numerically
- sorter = function (a, b) {
- return ((a + 0) - (b + 0));
- };
- break;
- // case 'SORT_REGULAR': // compare items normally (don't change types)
- default:
- sorter = function (a, b) {
- var aFloat = parseFloat(a),
- bFloat = parseFloat(b),
- aNumeric = aFloat + '' === a,
- bNumeric = bFloat + '' === b;
- if (aNumeric && bNumeric) {
- return aFloat > bFloat ? 1 : aFloat < bFloat ? -1 : 0;
- } else if (aNumeric && !bNumeric) {
- return 1;
- } else if (!aNumeric && bNumeric) {
- return -1;
- }
- return a > b ? 1 : a < b ? -1 : 0;
- };
- break;
- }
-
- // Make a list of key names
- for (k in inputArr) {
- if (inputArr.hasOwnProperty(k)) {
- keys.push(k);
- }
- }
- keys.sort(sorter);
-
- // BEGIN REDUNDANT
- this.php_js = this.php_js || {};
- this.php_js.ini = this.php_js.ini || {};
- // END REDUNDANT
- strictForIn = this.php_js.ini['phpjs.strictForIn'] && this.php_js.ini['phpjs.strictForIn'].local_value && this.php_js.ini['phpjs.strictForIn'].local_value !== 'off';
- populateArr = strictForIn ? inputArr : populateArr;
-
- // Rebuild array with sorted key names
- for (i = 0; i < keys.length; i++) {
- k = keys[i];
- tmp_arr[k] = inputArr[k];
- if (strictForIn) {
- delete inputArr[k];
- }
- }
- for (i in tmp_arr) {
- if (tmp_arr.hasOwnProperty(i)) {
- populateArr[i] = tmp_arr[i];
- }
- }
-
- return strictForIn || populateArr;
- };
-
- php.lcfirst = function (str) {
- // !No description available for lcfirst. @php.js developers: Please update the function summary text file.
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/lcfirst
- // + original by: Brett Zamir (http://brett-zamir.me)
- // * example 1: \php.lcfirst('Kevin Van Zonneveld');
- // * returns 1: 'kevin Van Zonneveld'
- str += '';
- var f = str.charAt(0).toLowerCase();
- return f + str.substr(1);
- };
-
- php.ltrim = function (str, charlist) {
- // Strips whitespace from the beginning of a string
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/ltrim
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + input by: Erkekjetter
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfixed by: Onno Marsman
- // * example 1: \php.ltrim(' Kevin van Zonneveld ');
- // * returns 1: 'Kevin van Zonneveld '
- charlist = !charlist ? ' \\s\u00A0' : (charlist + '').replace(/([\[\]\(\)\.\?\/\*\{\}\+\$\^\:])/g, '$1');
- var re = new RegExp('^[' + charlist + ']+', 'g');
- return (str + '').replace(re, '');
- };
- php.rtrim = function (str, charlist) {
- // Removes trailing whitespace
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/rtrim
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + input by: Erkekjetter
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfixed by: Onno Marsman
- // + input by: rem
- // + bugfixed by: Brett Zamir (http://brett-zamir.me)
- // * example 1: rtrim(' Kevin van Zonneveld ');
- // * returns 1: ' Kevin van Zonneveld'
- charlist = !charlist ? ' \\s\u00A0' : (charlist + '').replace(/([\[\]\(\)\.\?\/\*\{\}\+\$\^\:])/g, '\\$1');
- var re = new RegExp('[' + charlist + ']+$', 'g');
- return (str + '').replace(re, '');
- };
- php.max = function () {
- // Return the highest value in an array or a series of arguments
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/max
- // + original by: Onno Marsman
- // + revised by: Onno Marsman
- // + tweaked by: Jack
- // % note: Long code cause we're aiming for maximum PHP compatibility
- // * example 1: \php.max(1, 3, 5, 6, 7);
- // * returns 1: 7
- // * example 2: \php.max([2, 4, 5]);
- // * returns 2: 5
- // * example 3: \php.max(0, 'hello');
- // * returns 3: 0
- // * example 4: \php.max('hello', 0);
- // * returns 4: 'hello'
- // * example 5: \php.max(-1, 'hello');
- // * returns 5: 'hello'
- // * example 6: \php.max([2, 4, 8], [2, 5, 7]);
- // * returns 6: [2, 5, 7]
- var ar, retVal, i = 0,
- n = 0;
- var argv = arguments,
- argc = argv.length;
-
- var _obj2Array = function (obj) {
- if (obj instanceof Array) {
- return obj;
- } else {
- var ar = [];
- for (var i in obj) {
- ar.push(obj[i]);
- }
- return ar;
- }
- }; //function _obj2Array
- var _compare = function (current, next) {
- var i = 0,
- n = 0,
- tmp = 0;
- var nl = 0,
- cl = 0;
-
- if (current === next) {
- return 0;
- } else if (typeof current == 'object') {
- if (typeof next == 'object') {
- current = _obj2Array(current);
- next = _obj2Array(next);
- cl = current.length;
- nl = next.length;
- if (nl > cl) {
- return 1;
- } else if (nl < cl) {
- return -1;
- } else {
- for (i = 0, n = cl; i < n; ++i) {
- tmp = _compare(current[i], next[i]);
- if (tmp == 1) {
- return 1;
- } else if (tmp == -1) {
- return -1;
- }
- }
- return 0;
- }
- } else {
- return -1;
- }
- } else if (typeof next == 'object') {
- return 1;
- } else if (isNaN(next) && !isNaN(current)) {
- if (current == 0) {
- return 0;
- } else {
- return (current < 0 ? 1 : -1);
- }
- } else if (isNaN(current) && !isNaN(next)) {
- if (next == 0) {
- return 0;
- } else {
- return (next > 0 ? 1 : -1);
- }
- } else {
- if (next == current) {
- return 0;
- } else {
- return (next > current ? 1 : -1);
- }
- }
- }; //function _compare
- if (argc === 0) {
- throw new Error('At least one value should be passed to max()');
- } else if (argc === 1) {
- if (typeof argv[0] === 'object') {
- ar = _obj2Array(argv[0]);
- } else {
- throw new Error('Wrong parameter count for max()');
- }
- if (ar.length === 0) {
- throw new Error('Array must contain at least one element for max()');
- }
- } else {
- ar = argv;
- }
-
- retVal = ar[0];
- for (i = 1, n = ar.length; i < n; ++i) {
- if (_compare(retVal, ar[i]) == 1) {
- retVal = ar[i];
- }
- }
-
- return retVal;
- };
-
- php.md5 = function (str) {
- // Calculate the md5 hash of a string
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/md5
- // + original by: Webtoolkit.info (http://www.webtoolkit.info/)
- // + namespaced by: Michael White (http://getsprink.com)
- // + tweaked by: Jack
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + input by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // - depends on: utf8_encode
- // * example 1: \php.md5('Kevin van Zonneveld');
- // * returns 1: '6e658d4bfcb59cc13f96c14450ac40b9'
- var xl;
-
- var rotateLeft = function (lValue, iShiftBits) {
- return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));
- };
-
- var addUnsigned = function (lX, lY) {
- var lX4, lY4, lX8, lY8, lResult;
- lX8 = (lX & 0x80000000);
- lY8 = (lY & 0x80000000);
- lX4 = (lX & 0x40000000);
- lY4 = (lY & 0x40000000);
- lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);
- if (lX4 & lY4) {
- return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
- }
- if (lX4 | lY4) {
- if (lResult & 0x40000000) {
- return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
- } else {
- return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
- }
- } else {
- return (lResult ^ lX8 ^ lY8);
- }
- };
-
- var _F = function (x, y, z) {
- return (x & y) | ((~x) & z);
- };
- var _G = function (x, y, z) {
- return (x & z) | (y & (~z));
- };
- var _H = function (x, y, z) {
- return (x ^ y ^ z);
- };
- var _I = function (x, y, z) {
- return (y ^ (x | (~z)));
- };
-
- var _FF = function (a, b, c, d, x, s, ac) {
- a = addUnsigned(a, addUnsigned(addUnsigned(_F(b, c, d), x), ac));
- return addUnsigned(rotateLeft(a, s), b);
- };
-
- var _GG = function (a, b, c, d, x, s, ac) {
- a = addUnsigned(a, addUnsigned(addUnsigned(_G(b, c, d), x), ac));
- return addUnsigned(rotateLeft(a, s), b);
- };
-
- var _HH = function (a, b, c, d, x, s, ac) {
- a = addUnsigned(a, addUnsigned(addUnsigned(_H(b, c, d), x), ac));
- return addUnsigned(rotateLeft(a, s), b);
- };
-
- var _II = function (a, b, c, d, x, s, ac) {
- a = addUnsigned(a, addUnsigned(addUnsigned(_I(b, c, d), x), ac));
- return addUnsigned(rotateLeft(a, s), b);
- };
-
- var convertToWordArray = function (str) {
- var lWordCount;
- var lMessageLength = str.length;
- var lNumberOfWords_temp1 = lMessageLength + 8;
- var lNumberOfWords_temp2 = (lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64;
- var lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16;
- var lWordArray = new Array(lNumberOfWords - 1);
- var lBytePosition = 0;
- var lByteCount = 0;
- while (lByteCount < lMessageLength) {
- lWordCount = (lByteCount - (lByteCount % 4)) / 4;
- lBytePosition = (lByteCount % 4) * 8;
- lWordArray[lWordCount] = (lWordArray[lWordCount] | (str.charCodeAt(lByteCount) << lBytePosition));
- lByteCount++;
- }
- lWordCount = (lByteCount - (lByteCount % 4)) / 4;
- lBytePosition = (lByteCount % 4) * 8;
- lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition);
- lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
- lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
- return lWordArray;
- };
-
- var wordToHex = function (lValue) {
- var wordToHexValue = "",
- wordToHexValue_temp = "",
- lByte, lCount;
- for (lCount = 0; lCount <= 3; lCount++) {
- lByte = (lValue >>> (lCount * 8)) & 255;
- wordToHexValue_temp = "0" + lByte.toString(16);
- wordToHexValue = wordToHexValue + wordToHexValue_temp.substr(wordToHexValue_temp.length - 2, 2);
- }
- return wordToHexValue;
- };
-
- var x = [],
- k, AA, BB, CC, DD, a, b, c, d, S11 = 7,
- S12 = 12,
- S13 = 17,
- S14 = 22,
- S21 = 5,
- S22 = 9,
- S23 = 14,
- S24 = 20,
- S31 = 4,
- S32 = 11,
- S33 = 16,
- S34 = 23,
- S41 = 6,
- S42 = 10,
- S43 = 15,
- S44 = 21;
-
- str = this.utf8_encode(str);
- x = convertToWordArray(str);
- a = 0x67452301;
- b = 0xEFCDAB89;
- c = 0x98BADCFE;
- d = 0x10325476;
-
- xl = x.length;
- for (k = 0; k < xl; k += 16) {
- AA = a;
- BB = b;
- CC = c;
- DD = d;
- a = _FF(a, b, c, d, x[k + 0], S11, 0xD76AA478);
- d = _FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756);
- c = _FF(c, d, a, b, x[k + 2], S13, 0x242070DB);
- b = _FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE);
- a = _FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF);
- d = _FF(d, a, b, c, x[k + 5], S12, 0x4787C62A);
- c = _FF(c, d, a, b, x[k + 6], S13, 0xA8304613);
- b = _FF(b, c, d, a, x[k + 7], S14, 0xFD469501);
- a = _FF(a, b, c, d, x[k + 8], S11, 0x698098D8);
- d = _FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF);
- c = _FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1);
- b = _FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE);
- a = _FF(a, b, c, d, x[k + 12], S11, 0x6B901122);
- d = _FF(d, a, b, c, x[k + 13], S12, 0xFD987193);
- c = _FF(c, d, a, b, x[k + 14], S13, 0xA679438E);
- b = _FF(b, c, d, a, x[k + 15], S14, 0x49B40821);
- a = _GG(a, b, c, d, x[k + 1], S21, 0xF61E2562);
- d = _GG(d, a, b, c, x[k + 6], S22, 0xC040B340);
- c = _GG(c, d, a, b, x[k + 11], S23, 0x265E5A51);
- b = _GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA);
- a = _GG(a, b, c, d, x[k + 5], S21, 0xD62F105D);
- d = _GG(d, a, b, c, x[k + 10], S22, 0x2441453);
- c = _GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681);
- b = _GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8);
- a = _GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6);
- d = _GG(d, a, b, c, x[k + 14], S22, 0xC33707D6);
- c = _GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87);
- b = _GG(b, c, d, a, x[k + 8], S24, 0x455A14ED);
- a = _GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905);
- d = _GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8);
- c = _GG(c, d, a, b, x[k + 7], S23, 0x676F02D9);
- b = _GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A);
- a = _HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942);
- d = _HH(d, a, b, c, x[k + 8], S32, 0x8771F681);
- c = _HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122);
- b = _HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C);
- a = _HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44);
- d = _HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9);
- c = _HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60);
- b = _HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70);
- a = _HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6);
- d = _HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA);
- c = _HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085);
- b = _HH(b, c, d, a, x[k + 6], S34, 0x4881D05);
- a = _HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039);
- d = _HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5);
- c = _HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8);
- b = _HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665);
- a = _II(a, b, c, d, x[k + 0], S41, 0xF4292244);
- d = _II(d, a, b, c, x[k + 7], S42, 0x432AFF97);
- c = _II(c, d, a, b, x[k + 14], S43, 0xAB9423A7);
- b = _II(b, c, d, a, x[k + 5], S44, 0xFC93A039);
- a = _II(a, b, c, d, x[k + 12], S41, 0x655B59C3);
- d = _II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92);
- c = _II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D);
- b = _II(b, c, d, a, x[k + 1], S44, 0x85845DD1);
- a = _II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F);
- d = _II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0);
- c = _II(c, d, a, b, x[k + 6], S43, 0xA3014314);
- b = _II(b, c, d, a, x[k + 13], S44, 0x4E0811A1);
- a = _II(a, b, c, d, x[k + 4], S41, 0xF7537E82);
- d = _II(d, a, b, c, x[k + 11], S42, 0xBD3AF235);
- c = _II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB);
- b = _II(b, c, d, a, x[k + 9], S44, 0xEB86D391);
- a = addUnsigned(a, AA);
- b = addUnsigned(b, BB);
- c = addUnsigned(c, CC);
- d = addUnsigned(d, DD);
- }
-
- var temp = wordToHex(a) + wordToHex(b) + wordToHex(c) + wordToHex(d);
-
- return temp.toLowerCase();
- };
-
- php.method_exists = function (obj, method) {
- // Checks if the class method exists
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/method_exists
- // + original by: Brett Zamir (http://brett-zamir.me)
- // * example 1: \php.function class_a() {this.meth1 = function () {return true;}};
- // * example 1: \php.var instance_a = new class_a();
- // * example 1: \php.method_exists(instance_a, 'meth1');
- // * returns 1: true
- // * example 2: \php.function class_a() {this.meth1 = function () {return true;}};
- // * example 2: \php.var instance_a = new class_a();
- // * example 2: \php.method_exists(instance_a, 'meth2');
- // * returns 2: false
- if (typeof obj === 'string') {
- return this.window[obj] && typeof this.window[obj][method] === 'function';
- }
-
- return typeof obj[method] === 'function';
- };
-
- php.microtime = function (get_as_float) {
- // Returns either a string or a float containing the current time in seconds and microseconds
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/microtime
- // + original by: Paulo Freitas
- // * example 1: \php.timeStamp = microtime(true);
- // * results 1: timeStamp > 1000000000 && timeStamp < 2000000000
- var now = new Date().getTime() / 1000;
- var s = parseInt(now, 10);
-
- return (get_as_float) ? now : (Math.round((now - s) * 1000) / 1000) + ' ' + s;
- };
-
- php.min = function () {
- // Return the lowest value in an array or a series of arguments
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/min
- // + original by: Onno Marsman
- // + revised by: Onno Marsman
- // + tweaked by: Jack
- // % note: Long code cause we're aiming for maximum PHP compatibility
- // * example 1: \php.min(1, 3, 5, 6, 7);
- // * returns 1: 1
- // * example 2: \php.min([2, 4, 5]);
- // * returns 2: 2
- // * example 3: \php.min(0, 'hello');
- // * returns 3: 0
- // * example 4: \php.min('hello', 0);
- // * returns 4: 'hello'
- // * example 5: \php.min(-1, 'hello');
- // * returns 5: -1
- // * example 6: \php.min([2, 4, 8], [2, 5, 7]);
- // * returns 6: [2, 4, 8]
- var ar, retVal, i = 0,
- n = 0;
- var argv = arguments,
- argc = argv.length;
-
- var _obj2Array = function (obj) {
- if (obj instanceof Array) {
- return obj;
- } else {
- var ar = [];
- for (var i in obj) {
- ar.push(obj[i]);
- }
- return ar;
- }
- }; //function _obj2Array
- var _compare = function (current, next) {
- var i = 0,
- n = 0,
- tmp = 0;
- var nl = 0,
- cl = 0;
-
- if (current === next) {
- return 0;
- } else if (typeof current == 'object') {
- if (typeof next == 'object') {
- current = _obj2Array(current);
- next = _obj2Array(next);
- cl = current.length;
- nl = next.length;
- if (nl > cl) {
- return 1;
- } else if (nl < cl) {
- return -1;
- } else {
- for (i = 0, n = cl; i < n; ++i) {
- tmp = _compare(current[i], next[i]);
- if (tmp == 1) {
- return 1;
- } else if (tmp == -1) {
- return -1;
- }
- }
- return 0;
- }
- } else {
- return -1;
- }
- } else if (typeof next == 'object') {
- return 1;
- } else if (isNaN(next) && !isNaN(current)) {
- if (current == 0) {
- return 0;
- } else {
- return (current < 0 ? 1 : -1);
- }
- } else if (isNaN(current) && !isNaN(next)) {
- if (next == 0) {
- return 0;
- } else {
- return (next > 0 ? 1 : -1);
- }
- } else {
- if (next == current) {
- return 0;
- } else {
- return (next > current ? 1 : -1);
- }
- }
- }; //function _compare
- if (argc === 0) {
- throw new Error('At least one value should be passed to min()');
- } else if (argc === 1) {
- if (typeof argv[0] === 'object') {
- ar = _obj2Array(argv[0]);
- } else {
- throw new Error('Wrong parameter count for min()');
- }
- if (ar.length === 0) {
- throw new Error('Array must contain at least one element for min()');
- }
- } else {
- ar = argv;
- }
-
- retVal = ar[0];
- for (i = 1, n = ar.length; i < n; ++i) {
- if (_compare(retVal, ar[i]) == -1) {
- retVal = ar[i];
- }
- }
-
- return retVal;
- };
-
- php.mktime = function () {
- // Get UNIX timestamp for a date
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/mktime
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: baris ozdil
- // + input by: gabriel paderni
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: FGFEmperor
- // + input by: Yannoo
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + input by: jakes
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfixed by: Marc Palau
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // + input by: 3D-GRAF
- // + bugfixed by: Brett Zamir (http://brett-zamir.me)
- // + input by: Chris
- // + revised by: Theriault
- // % note 1: The return values of the following examples are
- // % note 1: received only if your system's timezone is UTC.
- // * example 1: \php.mktime(14, 10, 2, 2, 1, 2008);
- // * returns 1: 1201875002
- // * example 2: \php.mktime(0, 0, 0, 0, 1, 2008);
- // * returns 2: 1196467200
- // * example 3: \php.make = mktime();
- // * example 3: \php.td = new Date();
- // * example 3: \php.real = Math.floor(td.getTime() / 1000);
- // * example 3: \php.diff = (real - make);
- // * results 3: diff < 5
- // * example 4: \php.mktime(0, 0, 0, 13, 1, 1997)
- // * returns 4: 883612800
- // * example 5: \php.mktime(0, 0, 0, 1, 1, 1998)
- // * returns 5: 883612800
- // * example 6: \php.mktime(0, 0, 0, 1, 1, 98)
- // * returns 6: 883612800
- // * example 7: \php.mktime(23, 59, 59, 13, 0, 2010)
- // * returns 7: 1293839999
- // * example 8: \php.mktime(0, 0, -1, 1, 1, 1970)
- // * returns 8: -1
- var d = new Date(),
- r = arguments,
- i = 0,
- e = ['Hours', 'Minutes', 'Seconds', 'Month', 'Date', 'FullYear'];
-
- for (i = 0; i < e.length; i++) {
- if (typeof r[i] === 'undefined') {
- r[i] = d['get' + e[i]]();
- r[i] += (i === 3); // +1 to fix JS months.
- } else {
- r[i] = parseInt(r[i], 10);
- if (isNaN(r[i])) {
- return false;
- }
- }
- }
-
- // Map years 0-69 to 2000-2069 and years 70-100 to 1970-2000.
- r[5] += (r[5] >= 0 ? (r[5] <= 69 ? 2e3 : (r[5] <= 100 ? 1900 : 0)) : 0);
-
- // Set year, month (-1 to fix JS months), and date.
- // !This must come before the call to setHours!
- d.setFullYear(r[5], r[3] - 1, r[4]);
-
- // Set hours, minutes, and seconds.
- d.setHours(r[0], r[1], r[2]);
-
- // Divide milliseconds by 1000 to return seconds and drop decimal.
- // Add 1 second if negative or it'll be off from PHP by 1 second.
- return (d.getTime() / 1e3 >> 0) - (d.getTime() < 0);
- };
-
- php.natcasesort = function (inputArr) {
- // Sort an array using case-insensitive natural sort
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/natcasesort
- // + original by: Brett Zamir (http://brett-zamir.me)
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // % note 1: This function deviates from PHP in returning a copy of the array instead
- // % note 1: of acting by reference and returning true; this was necessary because
- // % note 1: IE does not allow deleting and re-adding of properties without caching
- // % note 1: of property position; you can set the ini of "phpjs.strictForIn" to true to
- // % note 1: get the PHP behavior, but use this only if you are in an environment
- // % note 1: such as Firefox extensions where for-in iteration order is fixed and true
- // % note 1: property deletion is supported. Note that we intend to implement the PHP
- // % note 1: behavior by default if IE ever does allow it; only gives shallow copy since
- // % note 1: is by reference in PHP anyways
- // % note 2: We cannot use numbers as keys and have them be reordered since they
- // % note 2: adhere to numerical order in some implementations
- // - depends on: strnatcasecmp
- // * example 1: $array1 = {a:'IMG0.png', b:'img12.png', c:'img10.png', d:'img2.png', e:'img1.png', f:'IMG3.png'};
- // * example 1: $array1 = natcasesort($array1);
- // * returns 1: {a: 'IMG0.png', e: 'img1.png', d: 'img2.png', f: 'IMG3.png', c: 'img10.png', b: 'img12.png'}
- var valArr = [],
- keyArr = [],
- k, i, ret, that = this,
- strictForIn = false,
- populateArr = {};
-
- var bubbleSort = function (keyArr, inputArr) {
- var i, j, tempValue, tempKeyVal;
- for (i = inputArr.length - 2; i >= 0; i--) {
- for (j = 0; j <= i; j++) {
- ret = that.strnatcasecmp(inputArr[j + 1], inputArr[j]);
- if (ret < 0) {
- tempValue = inputArr[j];
- inputArr[j] = inputArr[j + 1];
- inputArr[j + 1] = tempValue;
- tempKeyVal = keyArr[j];
- keyArr[j] = keyArr[j + 1];
- keyArr[j + 1] = tempKeyVal;
- }
- }
- }
- };
-
- // BEGIN REDUNDANT
- this.php_js = this.php_js || {};
- this.php_js.ini = this.php_js.ini || {};
- // END REDUNDANT
- strictForIn = this.php_js.ini['phpjs.strictForIn'] && this.php_js.ini['phpjs.strictForIn'].local_value && this.php_js.ini['phpjs.strictForIn'].local_value !== 'off';
- populateArr = strictForIn ? inputArr : populateArr;
-
- // Get key and value arrays
- for (k in inputArr) {
- if (inputArr.hasOwnProperty(k)) {
- valArr.push(inputArr[k]);
- keyArr.push(k);
- if (strictForIn) {
- delete inputArr[k];
- }
- }
- }
-
- try {
- // Sort our new temporary arrays
- bubbleSort(keyArr, valArr);
- } catch (e) {
- return false;
- }
-
- // Repopulate the old array
- for (i = 0; i < valArr.length; i++) {
- populateArr[keyArr[i]] = valArr[i];
- }
-
- return strictForIn || populateArr;
- };
-
- php.natsort = function (inputArr) {
- // Sort an array using natural sort
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/natsort
- // + original by: Brett Zamir (http://brett-zamir.me)
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // % note 1: This function deviates from PHP in returning a copy of the array instead
- // % note 1: of acting by reference and returning true; this was necessary because
- // % note 1: IE does not allow deleting and re-adding of properties without caching
- // % note 1: of property position; you can set the ini of "phpjs.strictForIn" to true to
- // % note 1: get the PHP behavior, but use this only if you are in an environment
- // % note 1: such as Firefox extensions where for-in iteration order is fixed and true
- // % note 1: property deletion is supported. Note that we intend to implement the PHP
- // % note 1: behavior by default if IE ever does allow it; only gives shallow copy since
- // % note 1: is by reference in PHP anyways
- // - depends on: strnatcmp
- // * example 1: $array1 = {a:"img12.png", b:"img10.png", c:"img2.png", d:"img1.png"};
- // * example 1: $array1 = natsort($array1);
- // * returns 1: {d: 'img1.png', c: 'img2.png', b: 'img10.png', a: 'img12.png'}
- var valArr = [],
- keyArr = [],
- k, i, ret, that = this,
- strictForIn = false,
- populateArr = {};
-
- var bubbleSort = function (keyArr, inputArr) {
- var i, j, tempValue, tempKeyVal;
- for (i = inputArr.length - 2; i >= 0; i--) {
- for (j = 0; j <= i; j++) {
- ret = that.strnatcmp(inputArr[j + 1], inputArr[j]);
- if (ret < 0) {
- tempValue = inputArr[j];
- inputArr[j] = inputArr[j + 1];
- inputArr[j + 1] = tempValue;
- tempKeyVal = keyArr[j];
- keyArr[j] = keyArr[j + 1];
- keyArr[j + 1] = tempKeyVal;
- }
- }
- }
- };
-
- // BEGIN REDUNDANT
- this.php_js = this.php_js || {};
- this.php_js.ini = this.php_js.ini || {};
- // END REDUNDANT
- strictForIn = this.php_js.ini['phpjs.strictForIn'] && this.php_js.ini['phpjs.strictForIn'].local_value && this.php_js.ini['phpjs.strictForIn'].local_value !== 'off';
- populateArr = strictForIn ? inputArr : populateArr;
-
- // Get key and value arrays
- for (k in inputArr) {
- if (inputArr.hasOwnProperty(k)) {
- valArr.push(inputArr[k]);
- keyArr.push(k);
- if (strictForIn) {
- delete inputArr[k];
- }
- }
- }
- try {
- // Sort our new temporary arrays
- bubbleSort(keyArr, valArr);
- } catch (e) {
- return false;
- }
-
- // Repopulate the old array
- for (i = 0; i < valArr.length; i++) {
- populateArr[keyArr[i]] = valArr[i];
- }
-
- return strictForIn || populateArr;
- };
-
- php.nl2br = function (str, is_xhtml) {
- // Converts newlines to HTML line breaks
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/nl2br
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Philip Peterson
- // + improved by: Onno Marsman
- // + improved by: Atli Þór
- // + bugfixed by: Onno Marsman
- // + input by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // + improved by: Maximusya
- // * example 1: \php.nl2br('Kevin\nvan\nZonneveld');
- // * returns 1: 'Kevin<br />\nvan<br />\nZonneveld'
- // * example 2: \php.nl2br("\nOne\nTwo\n\nThree\n", false);
- // * returns 2: '<br>\nOne<br>\nTwo<br>\n<br>\nThree<br>\n'
- // * example 3: \php.nl2br("\nOne\nTwo\n\nThree\n", true);
- // * returns 3: '<br />\nOne<br />\nTwo<br />\n<br />\nThree<br />\n'
- var breakTag = (is_xhtml || typeof is_xhtml === 'undefined') ? '<br />' : '<br>';
-
- return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1' + breakTag + '$2');
- };
-
- php.number_format = function (number, decimals, dec_point, thousands_sep) {
- // Formats a number with grouped thousands
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/number_format
- // + original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfix by: Michael White (http://getsprink.com)
- // + bugfix by: Benjamin Lupton
- // + bugfix by: Allan Jensen (http://www.winternet.no)
- // + revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
- // + bugfix by: Howard Yeend
- // + revised by: Luke Smith (http://lucassmith.name)
- // + bugfix by: Diogo Resende
- // + bugfix by: Rival
- // + input by: Kheang Hok Chin (http://www.distantia.ca/)
- // + improved by: davook
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // + input by: Jay Klehr
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // + input by: Amir Habibi (http://www.residence-mixte.com/)
- // + bugfix by: Brett Zamir (http://brett-zamir.me)
- // + improved by: Theriault
- // + input by: Amirouche
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // * example 1: \php.number_format(1234.56);
- // * returns 1: '1,235'
- // * example 2: \php.number_format(1234.56, 2, ',', ' ');
- // * returns 2: '1 234,56'
- // * example 3: \php.number_format(1234.5678, 2, '.', '');
- // * returns 3: '1234.57'
- // * example 4: \php.number_format(67, 2, ',', '.');
- // * returns 4: '67,00'
- // * example 5: \php.number_format(1000);
- // * returns 5: '1,000'
- // * example 6: \php.number_format(67.311, 2);
- // * returns 6: '67.31'
- // * example 7: \php.number_format(1000.55, 1);
- // * returns 7: '1,000.6'
- // * example 8: \php.number_format(67000, 5, ',', '.');
- // * returns 8: '67.000,00000'
- // * example 9: \php.number_format(0.9, 0);
- // * returns 9: '1'
- // * example 10: \php.number_format('1.20', 2);
- // * returns 10: '1.20'
- // * example 11: \php.number_format('1.20', 4);
- // * returns 11: '1.2000'
- // * example 12: \php.number_format('1.2000', 3);
- // * returns 12: '1.200'
- // * example 13: \php.number_format('1 000,50', 2, '.', ' ');
- // * returns 13: '100 050.00'
- // Strip all characters but numerical ones.
- number = (number + '').replace(/[^0-9+\-Ee.]/g, '');
- var n = !isFinite(+number) ? 0 : +number,
- prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
- sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
- dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
- s = '',
- toFixedFix = function (n, prec) {
- var k = Math.pow(10, prec);
- return '' + Math.round(n * k) / k;
- };
- // Fix for IE parseFloat(0.55).toFixed(0) = 0;
- s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');
- if (s[0].length > 3) {
- s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
- }
- if ((s[1] || '').length < prec) {
- s[1] = s[1] || '';
- s[1] += new Array(prec - s[1].length + 1).join('0');
- }
- return s.join(dec);
- };
-
- php.ord = function (string) {
- // Returns the codepoint value of a character
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/ord
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfixed by: Onno Marsman
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // + input by: incidence
- // * example 1: \php.ord('K');
- // * returns 1: 75
- // * example 2: \php.ord('\uD800\uDC00'); // surrogate pair to create a single Unicode character
- // * returns 2: 65536
- var str = string + '',
- code = str.charCodeAt(0);
- if (0xD800 <= code && code <= 0xDBFF) { // High surrogate (could change last hex to 0xDB7F to treat high private surrogates as single characters)
- var hi = code;
- if (str.length === 1) {
- return code; // This is just a high surrogate with no following low surrogate, so we return its value;
- // we could also throw an error as it is not a complete character, but someone may want to know
- }
- var low = str.charCodeAt(1);
- return ((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;
- }
- if (0xDC00 <= code && code <= 0xDFFF) { // Low surrogate
- return code; // This is just a low surrogate with no preceding high surrogate, so we return its value;
- // we could also throw an error as it is not a complete character, but someone may want to know
- }
- return code;
- };
-
- php.parse_str = function (str, array) {
- // Parses GET/POST/COOKIE data and sets global variables
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/parse_str
- // + original by: Cagri Ekin
- // + improved by: Michael White (http://getsprink.com)
- // + tweaked by: Jack
- // + bugfixed by: Onno Marsman
- // + reimplemented by: stag019
- // + bugfixed by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: stag019
- // - depends on: urldecode
- // + input by: Dreamer
- // + bugfixed by: Brett Zamir (http://brett-zamir.me)
- // % note 1: When no argument is specified, will put variables in global scope.
- // * example 1: \php.var arr = {};
- // * example 1: \php.parse_str('first=foo&second=bar', arr);
- // * results 1: arr == { first: 'foo', second: 'bar' }
- // * example 2: \php.var arr = {};
- // * example 2: \php.parse_str('str_a=Jack+and+Jill+didn%27t+see+the+well.', arr);
- // * results 2: arr == { str_a: "Jack and Jill didn't see the well." }
- var glue1 = '=',
- glue2 = '&',
- array2 = String(str).replace(/^&?([\s\S]*?)&?$/, '$1').split(glue2),
- i, j, chr, tmp, key, value, bracket, keys, evalStr, that = this,
- fixStr = function (str) {
- return that.urldecode(str).replace(/([\\"'])/g, '\\$1').replace(/\n/g, '\\n').replace(/\r/g, '\\r');
- };
-
- if (!array) {
- array = this.window;
- }
-
- for (i = 0; i < array2.length; i++) {
- tmp = array2[i].split(glue1);
- if (tmp.length < 2) {
- tmp = [tmp, ''];
- }
- key = fixStr(tmp[0]);
- value = fixStr(tmp[1]);
- while (key.charAt(0) === ' ') {
- key = key.substr(1);
- }
- if (key.indexOf('\0') !== -1) {
- key = key.substr(0, key.indexOf('\0'));
- }
- if (key && key.charAt(0) !== '[') {
- keys = [];
- bracket = 0;
- for (j = 0; j < key.length; j++) {
- if (key.charAt(j) === '[' && !bracket) {
- bracket = j + 1;
- } else if (key.charAt(j) === ']') {
- if (bracket) {
- if (!keys.length) {
- keys.push(key.substr(0, bracket - 1));
- }
- keys.push(key.substr(bracket, j - bracket));
- bracket = 0;
- if (key.charAt(j + 1) !== '[') {
- break;
- }
- }
- }
- }
- if (!keys.length) {
- keys = [key];
- }
- for (j = 0; j < keys[0].length; j++) {
- chr = keys[0].charAt(j);
- if (chr === ' ' || chr === '.' || chr === '[') {
- keys[0] = keys[0].substr(0, j) + '_' + keys[0].substr(j + 1);
- }
- if (chr === '[') {
- break;
- }
- }
- evalStr = 'array';
- for (j = 0; j < keys.length; j++) {
- key = keys[j];
- if ((key !== '' && key !== ' ') || j === 0) {
- key = "'" + key + "'";
- } else {
- key = eval(evalStr + '.push([]);') - 1;
- }
- evalStr += '[' + key + ']';
- if (j !== keys.length - 1 && eval('typeof ' + evalStr) === 'undefined') {
- eval(evalStr + ' = [];');
- }
- }
- evalStr += " = '" + value + "';\n";
- eval(evalStr);
- }
- }
- };
-
- php.parse_url = function (str, component) {
- // Parse a URL and return its components
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/parse_url
- // + original by: Steven Levithan (http://blog.stevenlevithan.com)
- // + reimplemented by: Brett Zamir (http://brett-zamir.me)
- // + input by: Lorenzo Pisani
- // + input by: Tony
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // % note: Based on http://stevenlevithan.com/demo/parseuri/js/assets/parseuri.js
- // % note: blog post at http://blog.stevenlevithan.com/archives/parseuri
- // % note: demo at http://stevenlevithan.com/demo/parseuri/js/assets/parseuri.js
- // % note: Does not replace invalid characters with '_' as in PHP, nor does it return false with
- // % note: a seriously malformed URL.
- // % note: Besides function name, is essentially the same as parseUri as well as our allowing
- // % note: an extra slash after the scheme/protocol (to allow file:/// as in PHP)
- // * example 1: \php.parse_url('http://username:password@hostname/path?arg=value#anchor');
- // * returns 1: {scheme: 'http', host: 'hostname', user: 'username', pass: 'password', path: '/path', query: 'arg=value', fragment: 'anchor'}
- var key = ['source', 'scheme', 'authority', 'userInfo', 'user', 'pass', 'host', 'port',
- 'relative', 'path', 'directory', 'file', 'query', 'fragment'],
- ini = (this.php_js && this.php_js.ini) || {},
- mode = (ini['phpjs.parse_url.mode'] &&
- ini['phpjs.parse_url.mode'].local_value) || 'php',
- parser = {
- php: /^(?:([^:\/?#]+):)?(?:\/\/()(?:(?:()(?:([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?()(?:(()(?:(?:[^?#\/]*\/)*)()(?:[^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
- strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
- loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/\/?)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ // Added one optional slash to post-scheme to catch file:/// (should restrict this)
- };
-
- var m = parser[mode].exec(str),
- uri = {},
- i = 14;
- while (i--) {
- if (m[i]) {
- uri[key[i]] = m[i];
- }
- }
-
- if (component) {
- return uri[component.replace('PHP_URL_', '').toLowerCase()];
- }
- if (mode !== 'php') {
- var name = (ini['phpjs.parse_url.queryKey'] &&
- ini['phpjs.parse_url.queryKey'].local_value) || 'queryKey';
- parser = /(?:^|&)([^&=]*)=?([^&]*)/g;
- uri[name] = {};
- uri[key[12]].replace(parser, function ($0, $1, $2) {
- if ($1) {uri[name][$1] = $2;}
- });
- }
- delete uri.source;
- return uri;
- };
-
- php.printf = function () {
- // Output a formatted string
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/printf
- // + original by: Ash Searle (http://hexmen.com/blog/)
- // + improved by: Michael White (http://getsprink.com)
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // - depends on: sprintf
- // * example 1: \php.printf("%01.2f", 123.1);
- // * returns 1: 6
- var body, elmt, d = this.window.document;
- var ret = '';
-
- var HTMLNS = 'http://www.w3.org/1999/xhtml';
- body = d.getElementsByTagNameNS ? (d.getElementsByTagNameNS(HTMLNS, 'body')[0] ? d.getElementsByTagNameNS(HTMLNS, 'body')[0] : d.documentElement.lastChild) : d.getElementsByTagName('body')[0];
-
- if (!body) {
- return false;
- }
-
- ret = this.sprintf.apply(this, arguments);
-
- elmt = d.createTextNode(ret);
- body.appendChild(elmt);
-
- return ret.length;
- };
-
- php.property_exists = function (cls, prop) {
- // Checks if the object or class has a property
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/property_exists
- // + original by: Brett Zamir (http://brett-zamir.me)
- // * example 1: \php.function class_a () {this.prop1 = 'one'};
- // * example 1: \php.var instance_a = new class_a();
- // * example 1: \php.property_exists(instance_a, 'prop1');
- // * returns 1: true
- // * example 2: \php.function class_a () {this.prop1 = 'one'};
- // * example 2: \php.var instance_a = new class_a();
- // * example 2: \php.property_exists(instance_a, 'prop2');
- // * returns 2: false
- cls = (typeof cls === 'string') ? this.window[cls] : cls;
-
- if (typeof cls === 'function' && cls.toSource && cls.toSource().match(new RegExp('this\\.' + prop + '\\s'))) {
- // Hackish and non-standard but can probably detect if setting
- // the property (we don't want to test by instantiating as that
- // may have side-effects)
- return true;
- }
-
- return (cls[prop] !== undefined && typeof cls[prop] !== 'function') || (cls.prototype !== undefined && cls.prototype[prop] !== undefined && typeof cls.prototype[prop] !== 'function') || (cls.constructor && cls.constructor[prop] !== undefined && typeof cls.constructor[prop] !== 'function');
- };
-
- php.quotemeta = function (str) {
- // Quotes meta characters
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/quotemeta
- // + original by: Paulo Freitas
- // * example 1: \php.quotemeta(". + * ? ^ ( $ )");
- // * returns 1: '\. \+ \* \? \^ \( \$ \)'
- return (str + '').replace(/([\.\\\+\*\?\[\^\]\$\(\)])/g, '\\$1');
- };
-
- php.rand = function (min, max) {
- // Returns a random number
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/rand
- // + original by: Leslie Hoare
- // + bugfixed by: Onno Marsman
- // % note 1: See the commented out code below for a version which will work with our experimental (though probably unnecessary) srand() function)
- // * example 1: \php.rand(1, 1);
- // * returns 1: 1
- var argc = arguments.length;
- if (argc === 0) {
- min = 0;
- max = 2147483647;
- } else if (argc === 1) {
- throw new Error('Warning: rand() expects exactly 2 parameters, 1 given');
- }
- return Math.floor(Math.random() * (max - min + 1)) + min;
-
- /*
- // See note above for an explanation of the following alternative code
-
- // + reimplemented by: Brett Zamir (http://brett-zamir.me)
- // - depends on: srand
- // % note 1: This is a very possibly imperfect adaptation from the PHP source code
- var rand_seed, ctx, PHP_RAND_MAX=2147483647; // 0x7fffffff
-
- if (!this.php_js || this.php_js.rand_seed === undefined) {
- this.srand();
- }
- rand_seed = this.php_js.rand_seed;
-
- var argc = arguments.length;
- if (argc === 1) {
- throw new Error('Warning: rand() expects exactly 2 parameters, 1 given');
- }
-
- var do_rand = function (ctx) {
- return ((ctx * 1103515245 + 12345) % (PHP_RAND_MAX + 1));
- };
-
- var php_rand = function (ctxArg) { // php_rand_r
- this.php_js.rand_seed = do_rand(ctxArg);
- return parseInt(this.php_js.rand_seed, 10);
- };
-
- var number = php_rand(rand_seed);
-
- if (argc === 2) {
- number = min + parseInt(parseFloat(parseFloat(max) - min + 1.0) * (number/(PHP_RAND_MAX + 1.0)), 10);
- }
- return number;
- */
- };
-
- php.range = function (low, high, step) {
- // Create an array containing the range of integers or characters from low to high (inclusive)
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/range
- // + original by: Waldo Malqui Silva
- // * example 1: \php.range ( 0, 12 );
- // * returns 1: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
- // * example 2: \php.range( 0, 100, 10 );
- // * returns 2: [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
- // * example 3: \php.range( 'a', 'i' );
- // * returns 3: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
- // * example 4: \php.range( 'c', 'a' );
- // * returns 4: ['c', 'b', 'a']
- var matrix = [];
- var inival, endval, plus;
- var walker = step || 1;
- var chars = false;
-
- if (!isNaN(low) && !isNaN(high)) {
- inival = low;
- endval = high;
- } else if (isNaN(low) && isNaN(high)) {
- chars = true;
- inival = low.charCodeAt(0);
- endval = high.charCodeAt(0);
- } else {
- inival = (isNaN(low) ? 0 : low);
- endval = (isNaN(high) ? 0 : high);
- }
-
- plus = ((inival > endval) ? false : true);
- if (plus) {
- while (inival <= endval) {
- matrix.push(((chars) ? String.fromCharCode(inival) : inival));
- inival += walker;
- }
- } else {
- while (inival >= endval) {
- matrix.push(((chars) ? String.fromCharCode(inival) : inival));
- inival -= walker;
- }
- }
-
- return matrix;
- };
-
- php.reset = function (arr) {
- // Set array argument's internal pointer to the first element and return it
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/reset
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfixed by: Legaev Andrey
- // + revised by: Brett Zamir (http://brett-zamir.me)
- // % note 1: Uses global: php_js to store the array pointer
- // * example 1: \php.reset({0: 'Kevin', 1: 'van', 2: 'Zonneveld'});
- // * returns 1: 'Kevin'
- // BEGIN REDUNDANT
- this.php_js = this.php_js || {};
- this.php_js.pointers = this.php_js.pointers || [];
- var indexOf = function (value) {
- for (var i = 0, length = this.length; i < length; i++) {
- if (this[i] === value) {
- return i;
- }
- }
- return -1;
- };
- // END REDUNDANT
- var pointers = this.php_js.pointers;
- if (!pointers.indexOf) {
- pointers.indexOf = indexOf;
- }
- if (pointers.indexOf(arr) === -1) {
- pointers.push(arr, 0);
- }
- var arrpos = pointers.indexOf(arr);
- if (!(arr instanceof Array)) {
- for (var k in arr) {
- if (pointers.indexOf(arr) === -1) {
- pointers.push(arr, 0);
- } else {
- pointers[arrpos + 1] = 0;
- }
- return arr[k];
- }
- return false; // Empty
- }
- if (arr.length === 0) {
- return false;
- }
- pointers[arrpos + 1] = 0;
- return arr[pointers[arrpos + 1]];
- };
-
- php.round = function (value, precision, mode) {
- // Returns the number rounded to specified precision
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/round
- // + original by: Philip Peterson
- // + revised by: Onno Marsman
- // + input by: Greenseed
- // + revised by: T.Wild
- // + input by: meo
- // + input by: William
- // + bugfixed by: Brett Zamir (http://brett-zamir.me)
- // + input by: Josep Sanz (http://www.ws3.es/)
- // + revised by: Rafał Kukawski (http://blog.kukawski.pl/)
- // % note 1: Great work. Ideas for improvement:
- // % note 1: - code more compliant with developer guidelines
- // % note 1: - for implementing PHP constant arguments look at
- // % note 1: the pathinfo() function, it offers the greatest
- // % note 1: flexibility & compatibility possible
- // * example 1: \php.round(1241757, -3);
- // * returns 1: 1242000
- // * example 2: \php.round(3.6);
- // * returns 2: 4
- // * example 3: \php.round(2.835, 2);
- // * returns 3: 2.84
- // * example 4: \php.round(1.1749999999999, 2);
- // * returns 4: 1.17
- // * example 5: \php.round(58551.799999999996, 2);
- // * returns 5: 58551.8
- var m, f, isHalf, sgn; // helper variables
- precision |= 0; // making sure precision is integer
- m = Math.pow(10, precision);
- value *= m;
- sgn = (value > 0) | -(value < 0); // sign of the number
- isHalf = value % 1 === 0.5 * sgn;
- f = Math.floor(value);
-
- if (isHalf) {
- switch (mode) {
- case 'PHP_ROUND_HALF_DOWN':
- value = f + (sgn < 0); // rounds .5 toward zero
- break;
- case 'PHP_ROUND_HALF_EVEN':
- value = f + (f % 2 * sgn); // rouds .5 towards the next even integer
- break;
- case 'PHP_ROUND_HALF_ODD':
- value = f + !(f % 2); // rounds .5 towards the next odd integer
- break;
- default:
- value = f + (sgn > 0); // rounds .5 away from zero
- }
- }
-
- return (isHalf ? value : Math.round(value)) / m;
- };
-
- php.rsort = function (inputArr, sort_flags) {
- // Sort an array in reverse order
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/rsort
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + revised by: Brett Zamir (http://brett-zamir.me)
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // % note 1: SORT_STRING (as well as natsort and natcasesort) might also be
- // % note 1: integrated into all of these functions by adapting the code at
- // % note 1: http://sourcefrog.net/projects/natsort/natcompare.js
- // % note 2: This function deviates from PHP in returning a copy of the array instead
- // % note 2: of acting by reference and returning true; this was necessary because
- // % note 2: IE does not allow deleting and re-adding of properties without caching
- // % note 2: of property position; you can set the ini of "phpjs.strictForIn" to true to
- // % note 2: get the PHP behavior, but use this only if you are in an environment
- // % note 2: such as Firefox extensions where for-in iteration order is fixed and true
- // % note 2: property deletion is supported. Note that we intend to implement the PHP
- // % note 2: behavior by default if IE ever does allow it; only gives shallow copy since
- // % note 2: is by reference in PHP anyways
- // % note 3: Since JS objects' keys are always strings, and (the
- // % note 3: default) SORT_REGULAR flag distinguishes by key type,
- // % note 3: if the content is a numeric string, we treat the
- // % note 3: "original type" as numeric.
- // - depends on: i18n_loc_get_default
- // * example 1: \php.rsort(['Kevin', 'van', 'Zonneveld']);
- // * returns 1: ['van', 'Zonneveld', 'Kevin']
- // * example 2: \php.ini_set('phpjs.strictForIn', true);
- // * example 2: \php.fruits = {d: 'lemon', a: 'orange', b: 'banana', c: 'apple'};
- // * example 2: \php.rsort(fruits);
- // * results 2: fruits == {0: 'orange', 1: 'lemon', 2: 'banana', 3: 'apple'}
- // * returns 2: true
- var valArr = [],
- k = '',
- i = 0,
- sorter = false,
- that = this,
- strictForIn = false,
- populateArr = [];
-
- switch (sort_flags) {
- case 'SORT_STRING':
- // compare items as strings
- sorter = function (a, b) {
- return that.strnatcmp(b, a);
- };
- break;
- case 'SORT_LOCALE_STRING':
- // compare items as strings, based on the current locale (set with i18n_loc_set_default() as of PHP6)
- var loc = this.i18n_loc_get_default();
- sorter = this.php_js.i18nLocales[loc].sorting;
- break;
- case 'SORT_NUMERIC':
- // compare items numerically
- sorter = function (a, b) {
- return (b - a);
- };
- break;
- case 'SORT_REGULAR':
- // compare items normally (don't change types)
- default:
- sorter = function (b, a) {
- var aFloat = parseFloat(a),
- bFloat = parseFloat(b),
- aNumeric = aFloat + '' === a,
- bNumeric = bFloat + '' === b;
- if (aNumeric && bNumeric) {
- return aFloat > bFloat ? 1 : aFloat < bFloat ? -1 : 0;
- } else if (aNumeric && !bNumeric) {
- return 1;
- } else if (!aNumeric && bNumeric) {
- return -1;
- }
- return a > b ? 1 : a < b ? -1 : 0;
- };
- break;
- }
-
- // BEGIN REDUNDANT
- this.php_js = this.php_js || {};
- this.php_js.ini = this.php_js.ini || {};
- // END REDUNDANT
- strictForIn = this.php_js.ini['phpjs.strictForIn'] && this.php_js.ini['phpjs.strictForIn'].local_value && this.php_js.ini['phpjs.strictForIn'].local_value !== 'off';
- populateArr = strictForIn ? inputArr : populateArr;
-
- for (k in inputArr) { // Get key and value arrays
- if (inputArr.hasOwnProperty(k)) {
- valArr.push(inputArr[k]);
- if (strictForIn) {
- delete inputArr[k];
- }
- }
- }
-
- valArr.sort(sorter);
-
- for (i = 0; i < valArr.length; i++) { // Repopulate the old array
- populateArr[i] = valArr[i];
- }
- return strictForIn || populateArr;
- };
-
- php.setcookie = function (name, value, expires, path, domain, secure) {
- // Send a cookie
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/setcookie
- // + original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
- // + bugfixed by: Andreas
- // + bugfixed by: Onno Marsman
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // - depends on: setrawcookie
- // * example 1: \php.setcookie('author_name', 'Kevin van Zonneveld');
- // * returns 1: true
- return this.setrawcookie(name, encodeURIComponent(value), expires, path, domain, secure);
- };
-
- php.setrawcookie = function (name, value, expires, path, domain, secure) {
- // Send a cookie with no url encoding of the value
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/setrawcookie
- // + original by: Brett Zamir (http://brett-zamir.me)
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + derived from: setcookie
- // + input by: Michael
- // + bugfixed by: Brett Zamir (http://brett-zamir.me)
- // * example 1: \php.setcookie('author_name', 'Kevin van Zonneveld');
- // * returns 1: true
- if (typeof expires === 'string' && (/^\d+$/).test(expires)) {
- expires = parseInt(expires, 10);
- }
-
- if (expires instanceof Date) {
- expires = expires.toGMTString();
- } else if (typeof(expires) === 'number') {
- expires = (new Date(expires * 1e3)).toGMTString();
- }
-
- var r = [name + '=' + value],
- s = {},
- i = '';
- s = {
- expires: expires,
- path: path,
- domain: domain
- };
- for (i in s) {
- if (s.hasOwnProperty(i)) { // Exclude items on Object.prototype
- s[i] && r.push(i + '=' + s[i]);
- }
- }
-
- return secure && r.push('secure'), this.window.document.cookie = r.join(";"), true;
- };
-
- php.sha1 = function (str) {
- // Calculate the sha1 hash of a string
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/sha1
- // + original by: Webtoolkit.info (http://www.webtoolkit.info/)
- // + namespaced by: Michael White (http://getsprink.com)
- // + input by: Brett Zamir (http://brett-zamir.me)
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // - depends on: utf8_encode
- // * example 1: \php.sha1('Kevin van Zonneveld');
- // * returns 1: '54916d2e62f65b3afa6e192e6a601cdbe5cb5897'
- var rotate_left = function (n, s) {
- var t4 = (n << s) | (n >>> (32 - s));
- return t4;
- };
-
- /*var lsb_hex = function (val) { // Not in use; needed?
- var str="";
- var i;
- var vh;
- var vl;
-
- for ( i=0; i<=6; i+=2 ) {
- vh = (val>>>(i*4+4))&0x0f;
- vl = (val>>>(i*4))&0x0f;
- str += vh.toString(16) + vl.toString(16);
- }
- return str;
- };*/
-
- var cvt_hex = function (val) {
- var str = "";
- var i;
- var v;
-
- for (i = 7; i >= 0; i--) {
- v = (val >>> (i * 4)) & 0x0f;
- str += v.toString(16);
- }
- return str;
- };
-
- var blockstart;
- var i, j;
- var W = new Array(80);
- var H0 = 0x67452301;
- var H1 = 0xEFCDAB89;
- var H2 = 0x98BADCFE;
- var H3 = 0x10325476;
- var H4 = 0xC3D2E1F0;
- var A, B, C, D, E;
- var temp;
-
- str = this.utf8_encode(str);
- var str_len = str.length;
-
- var word_array = [];
- for (i = 0; i < str_len - 3; i += 4) {
- j = str.charCodeAt(i) << 24 | str.charCodeAt(i + 1) << 16 | str.charCodeAt(i + 2) << 8 | str.charCodeAt(i + 3);
- word_array.push(j);
- }
-
- switch (str_len % 4) {
- case 0:
- i = 0x080000000;
- break;
- case 1:
- i = str.charCodeAt(str_len - 1) << 24 | 0x0800000;
- break;
- case 2:
- i = str.charCodeAt(str_len - 2) << 24 | str.charCodeAt(str_len - 1) << 16 | 0x08000;
- break;
- case 3:
- i = str.charCodeAt(str_len - 3) << 24 | str.charCodeAt(str_len - 2) << 16 | str.charCodeAt(str_len - 1) << 8 | 0x80;
- break;
- }
-
- word_array.push(i);
-
- while ((word_array.length % 16) != 14) {
- word_array.push(0);
- }
-
- word_array.push(str_len >>> 29);
- word_array.push((str_len << 3) & 0x0ffffffff);
-
- for (blockstart = 0; blockstart < word_array.length; blockstart += 16) {
- for (i = 0; i < 16; i++) {
- W[i] = word_array[blockstart + i];
- }
- for (i = 16; i <= 79; i++) {
- W[i] = rotate_left(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);
- }
-
-
- A = H0;
- B = H1;
- C = H2;
- D = H3;
- E = H4;
-
- for (i = 0; i <= 19; i++) {
- temp = (rotate_left(A, 5) + ((B & C) | (~B & D)) + E + W[i] + 0x5A827999) & 0x0ffffffff;
- E = D;
- D = C;
- C = rotate_left(B, 30);
- B = A;
- A = temp;
- }
-
- for (i = 20; i <= 39; i++) {
- temp = (rotate_left(A, 5) + (B ^ C ^ D) + E + W[i] + 0x6ED9EBA1) & 0x0ffffffff;
- E = D;
- D = C;
- C = rotate_left(B, 30);
- B = A;
- A = temp;
- }
-
- for (i = 40; i <= 59; i++) {
- temp = (rotate_left(A, 5) + ((B & C) | (B & D) | (C & D)) + E + W[i] + 0x8F1BBCDC) & 0x0ffffffff;
- E = D;
- D = C;
- C = rotate_left(B, 30);
- B = A;
- A = temp;
- }
-
- for (i = 60; i <= 79; i++) {
- temp = (rotate_left(A, 5) + (B ^ C ^ D) + E + W[i] + 0xCA62C1D6) & 0x0ffffffff;
- E = D;
- D = C;
- C = rotate_left(B, 30);
- B = A;
- A = temp;
- }
-
- H0 = (H0 + A) & 0x0ffffffff;
- H1 = (H1 + B) & 0x0ffffffff;
- H2 = (H2 + C) & 0x0ffffffff;
- H3 = (H3 + D) & 0x0ffffffff;
- H4 = (H4 + E) & 0x0ffffffff;
- }
-
- temp = cvt_hex(H0) + cvt_hex(H1) + cvt_hex(H2) + cvt_hex(H3) + cvt_hex(H4);
- return temp.toLowerCase();
- };
-
- php.shuffle = function (inputArr) {
- // Randomly shuffle the contents of an array
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/shuffle
- // + original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
- // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + revised by: Brett Zamir (http://brett-zamir.me)
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // % note 1: This function deviates from PHP in returning a copy of the array instead
- // % note 1: of acting by reference and returning true; this was necessary because
- // % note 1: IE does not allow deleting and re-adding of properties without caching
- // % note 1: of property position; you can set the ini of "phpjs.strictForIn" to true to
- // % note 1: get the PHP behavior, but use this only if you are in an environment
- // % note 1: such as Firefox extensions where for-in iteration order is fixed and true
- // % note 1: property deletion is supported. Note that we intend to implement the PHP
- // % note 1: behavior by default if IE ever does allow it; only gives shallow copy since
- // % note 1: is by reference in PHP anyways
- // * example 1: \php.ini_set('phpjs.strictForIn', true);
- // * example 1: \php.shuffle({5:'a', 2:'3', 3:'c', 4:5, 'q':5});
- // * returns 1: {5:'a', 4:5, 'q':5, 3:'c', 2:'3'}
- // * example 2: \php.ini_set('phpjs.strictForIn', true);
- // * example 2: \php.var data = {5:'a', 2:'3', 3:'c', 4:5, 'q':5};
- // * example 2: \php.shuffle(data);
- // * results 2: {5:'a', 'q':5, 3:'c', 2:'3', 4:5}
- // * returns 2: true
- var valArr = [],
- k = '',
- i = 0,
- strictForIn = false,
- populateArr = [];
-
- for (k in inputArr) { // Get key and value arrays
- if (inputArr.hasOwnProperty(k)) {
- valArr.push(inputArr[k]);
- if (strictForIn) {
- delete inputArr[k];
- }
- }
- }
- valArr.sort(function () {
- return 0.5 - Math.random();
- });
-
- // BEGIN REDUNDANT
- this.php_js = this.php_js || {};
- this.php_js.ini = this.php_js.ini || {};
- // END REDUNDANT
- strictForIn = this.php_js.ini['phpjs.strictForIn'] && this.php_js.ini['phpjs.strictForIn'].local_value && this.php_js.ini['phpjs.strictForIn'].local_value !== 'off';
- populateArr = strictForIn ? inputArr : populateArr;
-
- for (i = 0; i < valArr.length; i++) { // Repopulate the old array
- populateArr[i] = valArr[i];
- }
-
- return strictForIn || populateArr;
- };
-
- php.sizeof = function (mixed_var, mode) {
- // !No description available for sizeof. @php.js developers: Please update the function summary text file.
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/sizeof
- // + original by: Philip Peterson
- // - depends on: count
- // * example 1: \php.sizeof([[0,0],[0,-4]], 'COUNT_RECURSIVE');
- // * returns 1: 6
- // * example 2: \php.sizeof({'one' : [1,2,3,4,5]}, 'COUNT_RECURSIVE');
- // * returns 2: 6
- return this.count(mixed_var, mode);
- };
-
- php.sort = function (inputArr, sort_flags) {
- // Sort an array
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/sort
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + revised by: Brett Zamir (http://brett-zamir.me)
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // % note 1: SORT_STRING (as well as natsort and natcasesort) might also be
- // % note 1: integrated into all of these functions by adapting the code at
- // % note 1: http://sourcefrog.net/projects/natsort/natcompare.js
- // % note 2: This function deviates from PHP in returning a copy of the array instead
- // % note 2: of acting by reference and returning true; this was necessary because
- // % note 2: IE does not allow deleting and re-adding of properties without caching
- // % note 2: of property position; you can set the ini of "phpjs.strictForIn" to true to
- // % note 2: get the PHP behavior, but use this only if you are in an environment
- // % note 2: such as Firefox extensions where for-in iteration order is fixed and true
- // % note 2: property deletion is supported. Note that we intend to implement the PHP
- // % note 2: behavior by default if IE ever does allow it; only gives shallow copy since
- // % note 2: is by reference in PHP anyways
- // % note 3: Since JS objects' keys are always strings, and (the
- // % note 3: default) SORT_REGULAR flag distinguishes by key type,
- // % note 3: if the content is a numeric string, we treat the
- // % note 3: "original type" as numeric.
- // - depends on: i18n_loc_get_default
- // * example 1: \php.sort(['Kevin', 'van', 'Zonneveld']);
- // * returns 1: ['Kevin', 'Zonneveld', 'van']
- // * example 2: \php.ini_set('phpjs.strictForIn', true);
- // * example 2: \php.fruits = {d: 'lemon', a: 'orange', b: 'banana', c: 'apple'};
- // * example 2: \php.sort(fruits);
- // * results 2: fruits == {0: 'apple', 1: 'banana', 2: 'lemon', 3: 'orange'}
- // * returns 2: true
- var valArr = [],
- keyArr = [],
- k = '',
- i = 0,
- sorter = false,
- that = this,
- strictForIn = false,
- populateArr = [];
-
- switch (sort_flags) {
- case 'SORT_STRING':
- // compare items as strings
- sorter = function (a, b) {
- return that.strnatcmp(a, b);
- };
- break;
- case 'SORT_LOCALE_STRING':
- // compare items as strings, based on the current locale (set with i18n_loc_set_default() as of PHP6)
- var loc = this.i18n_loc_get_default();
- sorter = this.php_js.i18nLocales[loc].sorting;
- break;
- case 'SORT_NUMERIC':
- // compare items numerically
- sorter = function (a, b) {
- return (a - b);
- };
- break;
- case 'SORT_REGULAR':
- // compare items normally (don't change types)
- default:
- sorter = function (a, b) {
- var aFloat = parseFloat(a),
- bFloat = parseFloat(b),
- aNumeric = aFloat + '' === a,
- bNumeric = bFloat + '' === b;
- if (aNumeric && bNumeric) {
- return aFloat > bFloat ? 1 : aFloat < bFloat ? -1 : 0;
- } else if (aNumeric && !bNumeric) {
- return 1;
- } else if (!aNumeric && bNumeric) {
- return -1;
- }
- return a > b ? 1 : a < b ? -1 : 0;
- };
- break;
- }
-
- // BEGIN REDUNDANT
- this.php_js = this.php_js || {};
- this.php_js.ini = this.php_js.ini || {};
- // END REDUNDANT
- strictForIn = this.php_js.ini['phpjs.strictForIn'] && this.php_js.ini['phpjs.strictForIn'].local_value && this.php_js.ini['phpjs.strictForIn'].local_value !== 'off';
- populateArr = strictForIn ? inputArr : populateArr;
-
- for (k in inputArr) { // Get key and value arrays
- if (inputArr.hasOwnProperty(k)) {
- valArr.push(inputArr[k]);
- if (strictForIn) {
- delete inputArr[k];
- }
- }
- }
-
- valArr.sort(sorter);
-
- for (i = 0; i < valArr.length; i++) { // Repopulate the old array
- populateArr[i] = valArr[i];
- }
- return strictForIn || populateArr;
- };
-
- php.sprintf = function () {
- // Return a formatted string
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/sprintf
- // + original by: Ash Searle (http://hexmen.com/blog/)
- // + namespaced by: Michael White (http://getsprink.com)
- // + tweaked by: Jack
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + input by: Paulo Freitas
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + input by: Brett Zamir (http://brett-zamir.me)
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // * example 1: \php.sprintf("%01.2f", 123.1);
- // * returns 1: 123.10
- // * example 2: \php.sprintf("[%10s]", 'monkey');
- // * returns 2: '[ monkey]'
- // * example 3: \php.sprintf("[%'#10s]", 'monkey');
- // * returns 3: '[####monkey]'
- var regex = /%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuidfegEG])/g;
- var a = arguments,
- i = 0,
- format = a[i++];
-
- // pad()
- var pad = function (str, len, chr, leftJustify) {
- if (!chr) {
- chr = ' ';
- }
- var padding = (str.length >= len) ? '' : Array(1 + len - str.length >>> 0).join(chr);
- return leftJustify ? str + padding : padding + str;
- };
-
- // justify()
- var justify = function (value, prefix, leftJustify, minWidth, zeroPad, customPadChar) {
- var diff = minWidth - value.length;
- if (diff > 0) {
- if (leftJustify || !zeroPad) {
- value = pad(value, minWidth, customPadChar, leftJustify);
- } else {
- value = value.slice(0, prefix.length) + pad('', diff, '0', true) + value.slice(prefix.length);
- }
- }
- return value;
- };
-
- // formatBaseX()
- var formatBaseX = function (value, base, prefix, leftJustify, minWidth, precision, zeroPad) {
- // Note: casts negative numbers to positive ones
- var number = value >>> 0;
- prefix = prefix && number && {
- '2': '0b',
- '8': '0',
- '16': '0x'
- }[base] || '';
- value = prefix + pad(number.toString(base), precision || 0, '0', false);
- return justify(value, prefix, leftJustify, minWidth, zeroPad);
- };
-
- // formatString()
- var formatString = function (value, leftJustify, minWidth, precision, zeroPad, customPadChar) {
- if (precision != null) {
- value = value.slice(0, precision);
- }
- return justify(value, '', leftJustify, minWidth, zeroPad, customPadChar);
- };
-
- // doFormat()
- var doFormat = function (substring, valueIndex, flags, minWidth, _, precision, type) {
- var number;
- var prefix;
- var method;
- var textTransform;
- var value;
-
- if (substring == '%%') {
- return '%';
- }
-
- // parse flags
- var leftJustify = false,
- positivePrefix = '',
- zeroPad = false,
- prefixBaseX = false,
- customPadChar = ' ';
- var flagsl = flags.length;
- for (var j = 0; flags && j < flagsl; j++) {
- switch (flags.charAt(j)) {
- case ' ':
- positivePrefix = ' ';
- break;
- case '+':
- positivePrefix = '+';
- break;
- case '-':
- leftJustify = true;
- break;
- case "'":
- customPadChar = flags.charAt(j + 1);
- break;
- case '0':
- zeroPad = true;
- break;
- case '#':
- prefixBaseX = true;
- break;
- }
- }
-
- // parameters may be null, undefined, empty-string or real valued
- // we want to ignore null, undefined and empty-string values
- if (!minWidth) {
- minWidth = 0;
- } else if (minWidth == '*') {
- minWidth = +a[i++];
- } else if (minWidth.charAt(0) == '*') {
- minWidth = +a[minWidth.slice(1, -1)];
- } else {
- minWidth = +minWidth;
- }
-
- // Note: undocumented perl feature:
- if (minWidth < 0) {
- minWidth = -minWidth;
- leftJustify = true;
- }
-
- if (!isFinite(minWidth)) {
- throw new Error('sprintf: (minimum-)width must be finite');
- }
-
- if (!precision) {
- precision = 'fFeE'.indexOf(type) > -1 ? 6 : (type == 'd') ? 0 : undefined;
- } else if (precision == '*') {
- precision = +a[i++];
- } else if (precision.charAt(0) == '*') {
- precision = +a[precision.slice(1, -1)];
- } else {
- precision = +precision;
- }
-
- // grab value using valueIndex if required?
- value = valueIndex ? a[valueIndex.slice(0, -1)] : a[i++];
-
- switch (type) {
- case 's':
- return formatString(String(value), leftJustify, minWidth, precision, zeroPad, customPadChar);
- case 'c':
- return formatString(String.fromCharCode(+value), leftJustify, minWidth, precision, zeroPad);
- case 'b':
- return formatBaseX(value, 2, prefixBaseX, leftJustify, minWidth, precision, zeroPad);
- case 'o':
- return formatBaseX(value, 8, prefixBaseX, leftJustify, minWidth, precision, zeroPad);
- case 'x':
- return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad);
- case 'X':
- return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad).toUpperCase();
- case 'u':
- return formatBaseX(value, 10, prefixBaseX, leftJustify, minWidth, precision, zeroPad);
- case 'i':
- case 'd':
- number = (+value) | 0;
- prefix = number < 0 ? '-' : positivePrefix;
- value = prefix + pad(String(Math.abs(number)), precision, '0', false);
- return justify(value, prefix, leftJustify, minWidth, zeroPad);
- case 'e':
- case 'E':
- case 'f':
- case 'F':
- case 'g':
- case 'G':
- number = +value;
- prefix = number < 0 ? '-' : positivePrefix;
- method = ['toExponential', 'toFixed', 'toPrecision']['efg'.indexOf(type.toLowerCase())];
- textTransform = ['toString', 'toUpperCase']['eEfFgG'.indexOf(type) % 2];
- value = prefix + Math.abs(number)[method](precision);
- return justify(value, prefix, leftJustify, minWidth, zeroPad)[textTransform]();
- default:
- return substring;
- }
- };
-
- return format.replace(regex, doFormat);
- };
-
- php.str_ireplace = function (search, replace, subject) {
- // Replaces all occurrences of search in haystack with replace / case-insensitive
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/str_ireplace
- // + original by: Martijn Wieringa
- // + input by: penutbutterjelly
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + tweaked by: Jack
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfixed by: Onno Marsman
- // + input by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfixed by: Philipp Lenssen
- // * example 1: \php.str_ireplace('l', 'l', 'HeLLo');
- // * returns 1: 'Hello'
- // * example 2: \php.str_ireplace('$', 'foo', '$bar');
- // * returns 2: 'foobar'
- var i, k = '';
- var searchl = 0;
- var reg;
-
- var escapeRegex = function (s) {
- return s.replace(/([\\\^\$*+\[\]?{}.=!:(|)])/g, '\\$1');
- };
-
- search += '';
- searchl = search.length;
- if (!(replace instanceof Array)) {
- replace = [replace];
- if (search instanceof Array) {
- // If search is an array and replace is a string,
- // then this replacement string is used for every value of search
- while (searchl > replace.length) {
- replace[replace.length] = replace[0];
- }
- }
- }
-
- if (!(search instanceof Array)) {
- search = [search];
- }
- while (search.length > replace.length) {
- // If replace has fewer values than search,
- // then an empty string is used for the rest of replacement values
- replace[replace.length] = '';
- }
-
- if (subject instanceof Array) {
- // If subject is an array, then the search and replace is performed
- // with every entry of subject , and the return value is an array as well.
- for (k in subject) {
- if (subject.hasOwnProperty(k)) {
- subject[k] = str_ireplace(search, replace, subject[k]);
- }
- }
- return subject;
- }
-
- searchl = search.length;
- for (i = 0; i < searchl; i++) {
- reg = new RegExp(escapeRegex(search[i]), 'gi');
- subject = subject.replace(reg, replace[i]);
- }
-
- return subject;
- };
-
- php.str_pad = function (input, pad_length, pad_string, pad_type) {
- // Returns input string padded on the left or right to specified length with pad_string
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/str_pad
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + namespaced by: Michael White (http://getsprink.com)
- // + input by: Marco van Oort
- // + bugfixed by: Brett Zamir (http://brett-zamir.me)
- // * example 1: \php.str_pad('Kevin van Zonneveld', 30, '-=', 'STR_PAD_LEFT');
- // * returns 1: '-=-=-=-=-=-Kevin van Zonneveld'
- // * example 2: \php.str_pad('Kevin van Zonneveld', 30, '-', 'STR_PAD_BOTH');
- // * returns 2: '------Kevin van Zonneveld-----'
- var half = '',
- pad_to_go;
-
- var str_pad_repeater = function (s, len) {
- var collect = '',
- i;
-
- while (collect.length < len) {
- collect += s;
- }
- collect = collect.substr(0, len);
-
- return collect;
- };
-
- input += '';
- pad_string = pad_string !== undefined ? pad_string : ' ';
-
- if (pad_type != 'STR_PAD_LEFT' && pad_type != 'STR_PAD_RIGHT' && pad_type != 'STR_PAD_BOTH') {
- pad_type = 'STR_PAD_RIGHT';
- }
- if ((pad_to_go = pad_length - input.length) > 0) {
- if (pad_type == 'STR_PAD_LEFT') {
- input = str_pad_repeater(pad_string, pad_to_go) + input;
- } else if (pad_type == 'STR_PAD_RIGHT') {
- input = input + str_pad_repeater(pad_string, pad_to_go);
- } else if (pad_type == 'STR_PAD_BOTH') {
- half = str_pad_repeater(pad_string, Math.ceil(pad_to_go / 2));
- input = half + input + half;
- input = input.substr(0, pad_length);
- }
- }
-
- return input;
- };
-
- php.str_repeat = function (input, multiplier) {
- // Returns the input string repeat mult times
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/str_repeat
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
- // * example 1: \php.str_repeat('-=', 10);
- // * returns 1: '-=-=-=-=-=-=-=-=-=-='
- return new Array(multiplier + 1).join(input);
- };
-
- php.str_replace = function (search, replace, subject, count) {
- // Replaces all occurrences of search in haystack with replace
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/str_replace
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Gabriel Paderni
- // + improved by: Philip Peterson
- // + improved by: Simon Willison (http://simonwillison.net)
- // + revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
- // + bugfixed by: Anton Ongson
- // + input by: Onno Marsman
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + tweaked by: Onno Marsman
- // + input by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + input by: Oleg Eremeev
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: Oleg Eremeev
- // % note 1: The count parameter must be passed as a string in order
- // % note 1: to find a global variable in which the result will be given
- // * example 1: \php.str_replace(' ', '.', 'Kevin van Zonneveld');
- // * returns 1: 'Kevin.van.Zonneveld'
- // * example 2: \php.str_replace(['{name}', 'l'], ['hello', 'm'], '{name}, lars');
- // * returns 2: 'hemmo, mars'
- var i = 0,
- j = 0,
- temp = '',
- repl = '',
- sl = 0,
- fl = 0,
- f = [].concat(search),
- r = [].concat(replace),
- s = subject,
- ra = r instanceof Array,
- sa = s instanceof Array;
- s = [].concat(s);
- if (count) {
- this.window[count] = 0;
- }
-
- for (i = 0, sl = s.length; i < sl; i++) {
- if (s[i] === '') {
- continue;
- }
- for (j = 0, fl = f.length; j < fl; j++) {
- temp = s[i] + '';
- repl = ra ? (r[j] !== undefined ? r[j] : '') : r[0];
- s[i] = (temp).split(f[j]).join(repl);
- if (count && s[i] !== temp) {
- this.window[count] += (temp.length - s[i].length) / f[j].length;
- }
- }
- }
- return sa ? s : s[0];
- };
-
- php.str_word_count = function (str, format, charlist) {
- // Counts the number of words inside a string. If format of 1 is specified, then the function will return an array containing all the words found inside the string. If format of 2 is specified, then the function will return an associated array where the position of the word is the key and the word itself is the value. For the purpose of this function, 'word' is defined as a locale dependent string containing alphabetic characters, which also may contain, but not start with "'" and "-" characters.
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/str_word_count
- // + original by: Ole Vrijenhoek
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfixed by: Brett Zamir (http://brett-zamir.me)
- // + input by: Bug?
- // + bugfixed by: Brett Zamir (http://brett-zamir.me)
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // - depends on: ctype_alpha
- // * example 1: \php.str_word_count("Hello fri3nd, you're\r\n looking good today!", 1);
- // * returns 1: ['Hello', 'fri', 'nd', "you're", 'looking', 'good', 'today']
- // * example 2: \php.str_word_count("Hello fri3nd, you're\r\n looking good today!", 2);
- // * returns 2: {0: 'Hello', 6: 'fri', 10: 'nd', 14: "you're", 29: 'looking', 46: 'good', 51: 'today'}
- // * example 3: \php.str_word_count("Hello fri3nd, you're\r\n looking good today!", 1, '\u00e0\u00e1\u00e3\u00e73');
- // * returns 3: ['Hello', 'fri3nd', 'youre', 'looking', 'good', 'today']
- var len = str.length,
- cl = charlist && charlist.length,
- chr = '',
- tmpStr = '',
- i = 0,
- c = '',
- wArr = [],
- wC = 0,
- assoc = {},
- aC = 0,
- reg = '',
- match = false;
-
- // BEGIN STATIC
- var _preg_quote = function (str) {
- return (str + '').replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!<>\|\:])/g, '\\$1');
- },
- _getWholeChar = function (str, i) { // Use for rare cases of non-BMP characters
- var code = str.charCodeAt(i);
- if (code < 0xD800 || code > 0xDFFF) {
- return str.charAt(i);
- }
- if (0xD800 <= code && code <= 0xDBFF) { // High surrogate (could change last hex to 0xDB7F to treat high private surrogates as single characters)
- if (str.length <= (i + 1)) {
- throw 'High surrogate without following low surrogate';
- }
- var next = str.charCodeAt(i + 1);
- if (0xDC00 > next || next > 0xDFFF) {
- throw 'High surrogate without following low surrogate';
- }
- return str.charAt(i) + str.charAt(i + 1);
- }
- // Low surrogate (0xDC00 <= code && code <= 0xDFFF)
- if (i === 0) {
- throw 'Low surrogate without preceding high surrogate';
- }
- var prev = str.charCodeAt(i - 1);
- if (0xD800 > prev || prev > 0xDBFF) { // (could change last hex to 0xDB7F to treat high private surrogates as single characters)
- throw 'Low surrogate without preceding high surrogate';
- }
- return false; // We can pass over low surrogates now as the second component in a pair which we have already processed
- };
- // END STATIC
- if (cl) {
- reg = '^(' + _preg_quote(_getWholeChar(charlist, 0));
- for (i = 1; i < cl; i++) {
- if ((chr = _getWholeChar(charlist, i)) === false) {
- continue;
- }
- reg += '|' + _preg_quote(chr);
- }
- reg += ')$';
- reg = new RegExp(reg);
- }
-
- for (i = 0; i < len; i++) {
- if ((c = _getWholeChar(str, i)) === false) {
- continue;
- }
- match = this.ctype_alpha(c) || (reg && c.search(reg) !== -1) || ((i !== 0 && i !== len - 1) && c === '-') || // No hyphen at beginning or end unless allowed in charlist (or locale)
- (i !== 0 && c === "'"); // No apostrophe at beginning unless allowed in charlist (or locale)
- if (match) {
- if (tmpStr === '' && format === 2) {
- aC = i;
- }
- tmpStr = tmpStr + c;
- }
- if (i === len - 1 || !match && tmpStr !== '') {
- if (format !== 2) {
- wArr[wArr.length] = tmpStr;
- } else {
- assoc[aC] = tmpStr;
- }
- tmpStr = '';
- wC++;
- }
- }
-
- if (!format) {
- return wC;
- } else if (format === 1) {
- return wArr;
- } else if (format === 2) {
- return assoc;
- }
- throw 'You have supplied an incorrect format';
- };
-
- php.strcasecmp = function (f_string1, f_string2) {
- // Binary safe case-insensitive string comparison
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/strcasecmp
- // + original by: Martijn Wieringa
- // + bugfixed by: Onno Marsman
- // * example 1: \php.strcasecmp('Hello', 'hello');
- // * returns 1: 0
- var string1 = (f_string1 + '').toLowerCase();
- var string2 = (f_string2 + '').toLowerCase();
-
- if (string1 > string2) {
- return 1;
- } else if (string1 == string2) {
- return 0;
- }
-
- return -1;
- };
-
- php.strcmp = function (str1, str2) {
- // Binary safe string comparison
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/strcmp
- // + original by: Waldo Malqui Silva
- // + input by: Steve Hilder
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + revised by: gorthaur
- // * example 1: \php.strcmp( 'waldo', 'owald' );
- // * returns 1: 1
- // * example 2: \php.strcmp( 'owald', 'waldo' );
- // * returns 2: -1
- return ((str1 == str2) ? 0 : ((str1 > str2) ? 1 : -1));
- };
-
- php.strcspn = function (str, mask, start, length) {
- // Finds length of initial segment consisting entirely of characters not found in mask. If start or/and length is provide works like strcspn(substr($s,$start,$len),$bad_chars)
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/strcspn
- // + original by: Brett Zamir (http://brett-zamir.me)
- // * example 1: \php.strcspn('abcdefg123', '1234567890');
- // * returns 1: 7
- // * example 2: \php.strcspn('123abc', '1234567890');
- // * returns 2: 3
- start = start ? start : 0;
- var count = (length && ((start + length) < str.length)) ? start + length : str.length;
- strct: for (var i = start, lgth = 0; i < count; i++) {
- for (var j = 0; j < mask.length; j++) {
- if (str.charAt(i).indexOf(mask[j]) !== -1) {
- continue strct;
- }
- }++lgth;
- }
-
- return lgth;
- };
-
- php.strip_tags = function (input, allowed) {
- // Strips HTML and PHP tags from a string
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/strip_tags
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Luke Godfrey
- // + input by: Pul
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfixed by: Onno Marsman
- // + input by: Alex
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + input by: Marc Palau
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + input by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfixed by: Eric Nagel
- // + input by: Bobby Drake
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfixed by: Tomasz Wesolowski
- // + input by: Evertjan Garretsen
- // + revised by: Rafał Kukawski (http://blog.kukawski.pl/)
- // * example 1: \php.strip_tags('<p>Kevin</p> <br /><b>van</b> <i>Zonneveld</i>', '<i><b>');
- // * returns 1: 'Kevin <b>van</b> <i>Zonneveld</i>'
- // * example 2: \php.strip_tags('<p>Kevin <img src="someimage.png" onmouseover="someFunction()">van <i>Zonneveld</i></p>', '<p>');
- // * returns 2: '<p>Kevin van Zonneveld</p>'
- // * example 3: \php.strip_tags("<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>", "<a>");
- // * returns 3: '<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>'
- // * example 4: \php.strip_tags('1 < 5 5 > 1');
- // * returns 4: '1 < 5 5 > 1'
- // * example 5: \php.strip_tags('1 <br/> 1');
- // * returns 5: '1 1'
- // * example 6: \php.strip_tags('1 <br/> 1', '<br>');
- // * returns 6: '1 1'
- // * example 7: \php.strip_tags('1 <br/> 1', '<br><br/>');
- // * returns 7: '1 <br/> 1'
- allowed = (((allowed || "") + "").toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join(''); // making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>)
- var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,
- commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi;
- return input.replace(commentsAndPhpTags, '').replace(tags, function ($0, $1) {
- return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
- });
- };
-
- php.stripos = function (f_haystack, f_needle, f_offset) {
- // Finds position of first occurrence of a string within another, case insensitive
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/stripos
- // + original by: Martijn Wieringa
- // + revised by: Onno Marsman
- // * example 1: \php.stripos('ABC', 'a');
- // * returns 1: 0
- var haystack = (f_haystack + '').toLowerCase();
- var needle = (f_needle + '').toLowerCase();
- var index = 0;
-
- if ((index = haystack.indexOf(needle, f_offset)) !== -1) {
- return index;
- }
- return false;
- };
-
- php.stripslashes = function (str) {
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Ates Goral (http://magnetiq.com)
- // + fixed by: Mick@el
- // + improved by: marrtins
- // + bugfixed by: Onno Marsman
- // + improved by: rezna
- // + input by: Rick Waldron
- // + reimplemented by: Brett Zamir (http://brett-zamir.me)
- // + input by: Brant Messenger (http://www.brantmessenger.com/)
- // + bugfixed by: Brett Zamir (http://brett-zamir.me)
- // * example 1: \php.stripslashes('Kevin\'s code');
- // * returns 1: "Kevin's code"
- // * example 2: \php.stripslashes('Kevin\\\'s code');
- // * returns 2: "Kevin\'s code"
- return (str + '').replace(/\\(.?)/g, function (s, n1) {
- switch (n1) {
- case '\\':
- return '\\';
- case '0':
- return '\u0000';
- case '':
- return '';
- default:
- return n1;
- }
- });
- };
-
- php.stristr = function (haystack, needle, bool) {
- // Finds first occurrence of a string within another, case insensitive
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/stristr
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfxied by: Onno Marsman
- // * example 1: \php.stristr('Kevin van Zonneveld', 'Van');
- // * returns 1: 'van Zonneveld'
- // * example 2: \php.stristr('Kevin van Zonneveld', 'VAN', true);
- // * returns 2: 'Kevin '
- var pos = 0;
-
- haystack += '';
- pos = haystack.toLowerCase().indexOf((needle + '').toLowerCase());
- if (pos == -1) {
- return false;
- } else {
- if (bool) {
- return haystack.substr(0, pos);
- } else {
- return haystack.slice(pos);
- }
- }
- };
-
- php.strlen = function (string) {
- // Get string length
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/strlen
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Sakimori
- // + input by: Kirk Strobeck
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfixed by: Onno Marsman
- // + revised by: Brett Zamir (http://brett-zamir.me)
- // % note 1: May look like overkill, but in order to be truly faithful to handling all Unicode
- // % note 1: characters and to this function in PHP which does not count the number of bytes
- // % note 1: but counts the number of characters, something like this is really necessary.
- // * example 1: \php.strlen('Kevin van Zonneveld');
- // * returns 1: 19
- // * example 2: \php.strlen('A\ud87e\udc04Z');
- // * returns 2: 3
- var str = string + '';
- var i = 0,
- chr = '',
- lgth = 0;
-
- if (!this.php_js || !this.php_js.ini || !this.php_js.ini['unicode.semantics'] || this.php_js.ini['unicode.semantics'].local_value.toLowerCase() !== 'on') {
- return string.length;
- }
-
- var getWholeChar = function (str, i) {
- var code = str.charCodeAt(i);
- var next = '',
- prev = '';
- if (0xD800 <= code && code <= 0xDBFF) { // High surrogate (could change last hex to 0xDB7F to treat high private surrogates as single characters)
- if (str.length <= (i + 1)) {
- throw 'High surrogate without following low surrogate';
- }
- next = str.charCodeAt(i + 1);
- if (0xDC00 > next || next > 0xDFFF) {
- throw 'High surrogate without following low surrogate';
- }
- return str.charAt(i) + str.charAt(i + 1);
- } else if (0xDC00 <= code && code <= 0xDFFF) { // Low surrogate
- if (i === 0) {
- throw 'Low surrogate without preceding high surrogate';
- }
- prev = str.charCodeAt(i - 1);
- if (0xD800 > prev || prev > 0xDBFF) { //(could change last hex to 0xDB7F to treat high private surrogates as single characters)
- throw 'Low surrogate without preceding high surrogate';
- }
- return false; // We can pass over low surrogates now as the second component in a pair which we have already processed
- }
- return str.charAt(i);
- };
-
- for (i = 0, lgth = 0; i < str.length; i++) {
- if ((chr = getWholeChar(str, i)) === false) {
- continue;
- } // Adapt this line at the top of any loop, passing in the whole string and the current iteration and returning a variable to represent the individual character; purpose is to treat the first part of a surrogate pair as the whole character and then ignore the second part
- lgth++;
- }
- return lgth;
- };
-
- php.strnatcasecmp = function (str1, str2) {
- // Returns the result of case-insensitive string comparison using 'natural' algorithm
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/strnatcasecmp
- // + original by: Martin Pool
- // + reimplemented by: Pierre-Luc Paour
- // + reimplemented by: Kristof Coomans (SCK-CEN (Belgian Nucleair Research Centre))
- // + reimplemented by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + input by: Devan Penner-Woelk
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // * example 1: \php.strnatcasecmp(10, 1);
- // * returns 1: 1
- // * example 1: \php.strnatcasecmp('1', '10');
- // * returns 1: -1
- var a = (str1 + '').toLowerCase();
- var b = (str2 + '').toLowerCase();
-
- var isWhitespaceChar = function (a) {
- return a.charCodeAt(0) <= 32;
- };
-
- var isDigitChar = function (a) {
- var charCode = a.charCodeAt(0);
- return (charCode >= 48 && charCode <= 57);
- };
-
- var compareRight = function (a, b) {
- var bias = 0;
- var ia = 0;
- var ib = 0;
-
- var ca;
- var cb;
-
- // The longest run of digits wins. That aside, the greatest
- // value wins, but we can't know that it will until we've scanned
- // both numbers to know that they have the same magnitude, so we
- // remember it in BIAS.
- for (var cnt = 0; true; ia++, ib++) {
- ca = a.charAt(ia);
- cb = b.charAt(ib);
-
- if (!isDigitChar(ca) && !isDigitChar(cb)) {
- return bias;
- } else if (!isDigitChar(ca)) {
- return -1;
- } else if (!isDigitChar(cb)) {
- return 1;
- } else if (ca < cb) {
- if (bias === 0) {
- bias = -1;
- }
- } else if (ca > cb) {
- if (bias === 0) {
- bias = 1;
- }
- } else if (ca === '0' && cb === '0') {
- return bias;
- }
- }
- };
-
- var ia = 0,
- ib = 0;
- var nza = 0,
- nzb = 0;
- var ca, cb;
- var result;
-
- while (true) {
- // only count the number of zeroes leading the last number compared
- nza = nzb = 0;
-
- ca = a.charAt(ia);
- cb = b.charAt(ib);
-
- // skip over leading spaces or zeros
- while (isWhitespaceChar(ca) || ca === '0') {
- if (ca === '0') {
- nza++;
- } else {
- // only count consecutive zeroes
- nza = 0;
- }
-
- ca = a.charAt(++ia);
- }
-
- while (isWhitespaceChar(cb) || cb === '0') {
- if (cb === '0') {
- nzb++;
- } else {
- // only count consecutive zeroes
- nzb = 0;
- }
-
- cb = b.charAt(++ib);
- }
-
- // process run of digits
- if (isDigitChar(ca) && isDigitChar(cb)) {
- if ((result = compareRight(a.substring(ia), b.substring(ib))) !== 0) {
- return result;
- }
- }
-
- if (ca === '0' && cb === '0') {
- // The strings compare the same. Perhaps the caller
- // will want to call strcmp to break the tie.
- return nza - nzb;
- }
-
- if (ca < cb) {
- return -1;
- } else if (ca > cb) {
- return +1;
- }
-
- ++ia;
- ++ib;
- }
- };
-
- php.strnatcmp = function (f_string1, f_string2, f_version) {
- // Returns the result of string comparison using 'natural' algorithm
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/strnatcmp
- // + original by: Martijn Wieringa
- // + namespaced by: Michael White (http://getsprink.com)
- // + tweaked by: Jack
- // + bugfixed by: Onno Marsman
- // - depends on: strcmp
- // % note: Added f_version argument against code guidelines, because it's so neat
- // * example 1: \php.strnatcmp('Price 12.9', 'Price 12.15');
- // * returns 1: 1
- // * example 2: \php.strnatcmp('Price 12.09', 'Price 12.15');
- // * returns 2: -1
- // * example 3: \php.strnatcmp('Price 12.90', 'Price 12.15');
- // * returns 3: 1
- // * example 4: \php.strnatcmp('Version 12.9', 'Version 12.15', true);
- // * returns 4: -6
- // * example 5: \php.strnatcmp('Version 12.15', 'Version 12.9', true);
- // * returns 5: 6
- var i = 0;
-
- if (f_version == undefined) {
- f_version = false;
- }
-
- var __strnatcmp_split = function (f_string) {
- var result = [];
- var buffer = '';
- var chr = '';
- var i = 0,
- f_stringl = 0;
-
- var text = true;
-
- f_stringl = f_string.length;
- for (i = 0; i < f_stringl; i++) {
- chr = f_string.substring(i, i + 1);
- if (chr.match(/\d/)) {
- if (text) {
- if (buffer.length > 0) {
- result[result.length] = buffer;
- buffer = '';
- }
-
- text = false;
- }
- buffer += chr;
- } else if ((text == false) && (chr == '.') && (i < (f_string.length - 1)) && (f_string.substring(i + 1, i + 2).match(/\d/))) {
- result[result.length] = buffer;
- buffer = '';
- } else {
- if (text == false) {
- if (buffer.length > 0) {
- result[result.length] = parseInt(buffer, 10);
- buffer = '';
- }
- text = true;
- }
- buffer += chr;
- }
- }
-
- if (buffer.length > 0) {
- if (text) {
- result[result.length] = buffer;
- } else {
- result[result.length] = parseInt(buffer, 10);
- }
- }
-
- return result;
- };
-
- var array1 = __strnatcmp_split(f_string1 + '');
- var array2 = __strnatcmp_split(f_string2 + '');
-
- var len = array1.length;
- var text = true;
-
- var result = -1;
- var r = 0;
-
- if (len > array2.length) {
- len = array2.length;
- result = 1;
- }
-
- for (i = 0; i < len; i++) {
- if (isNaN(array1[i])) {
- if (isNaN(array2[i])) {
- text = true;
-
- if ((r = this.strcmp(array1[i], array2[i])) != 0) {
- return r;
- }
- } else if (text) {
- return 1;
- } else {
- return -1;
- }
- } else if (isNaN(array2[i])) {
- if (text) {
- return -1;
- } else {
- return 1;
- }
- } else {
- if (text || f_version) {
- if ((r = (array1[i] - array2[i])) != 0) {
- return r;
- }
- } else {
- if ((r = this.strcmp(array1[i].toString(), array2[i].toString())) != 0) {
- return r;
- }
- }
-
- text = false;
- }
- }
-
- return result;
- };
-
- php.strncasecmp = function (argStr1, argStr2, len) {
- // Binary safe string comparison
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/strncasecmp
- // + original by: Saulo Vallory
- // + input by: Nate
- // + bugfixed by: Onno Marsman
- // % note: Returns < 0 if str1 is less than str2 ; > 0 if str1 is greater than str2 , and 0 if they are equal.
- // * example 1: \php.strncasecmp('Price 12.9', 'Price 12.15', 2);
- // * returns 1: 0
- // * example 2: \php.strncasecmp('Price 12.09', 'Price 12.15', 10);
- // * returns 2: -1
- // * example 3: \php.strncasecmp('Price 12.90', 'Price 12.15', 30);
- // * returns 3: 8
- // * example 4: \php.strncasecmp('Version 12.9', 'Version 12.15', 20);
- // * returns 4: 8
- // * example 5: \php.strncasecmp('Version 12.15', 'Version 12.9', 20);
- // * returns 5: -8
- var diff, i = 0;
- var str1 = (argStr1 + '').toLowerCase().substr(0, len);
- var str2 = (argStr2 + '').toLowerCase().substr(0, len);
-
- if (str1.length !== str2.length) {
- if (str1.length < str2.length) {
- len = str1.length;
- if (str2.substr(0, str1.length) == str1) {
- return str1.length - str2.length; // return the difference of chars
- }
- } else {
- len = str2.length;
- // str1 is longer than str2
- if (str1.substr(0, str2.length) == str2) {
- return str1.length - str2.length; // return the difference of chars
- }
- }
- } else {
- // Avoids trying to get a char that does not exist
- len = str1.length;
- }
-
- for (diff = 0, i = 0; i < len; i++) {
- diff = str1.charCodeAt(i) - str2.charCodeAt(i);
- if (diff !== 0) {
- return diff;
- }
- }
-
- return 0;
- };
-
- php.strncmp = function (str1, str2, lgth) {
- // Binary safe string comparison
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/strncmp
- // + original by: Waldo Malqui Silva
- // + input by: Steve Hilder
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + revised by: gorthaur
- // + reimplemented by: Brett Zamir (http://brett-zamir.me)
- // * example 1: \php.strncmp('aaa', 'aab', 2);
- // * returns 1: 0
- // * example 2: \php.strncmp('aaa', 'aab', 3 );
- // * returns 2: -1
- var s1 = (str1 + '').substr(0, lgth);
- var s2 = (str2 + '').substr(0, lgth);
-
- return ((s1 == s2) ? 0 : ((s1 > s2) ? 1 : -1));
- };
-
- php.strpos = function (haystack, needle, offset) {
- // Finds position of first occurrence of a string within another
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/strpos
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Onno Marsman
- // + bugfixed by: Daniel Esteban
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // * example 1: \php.strpos('Kevin van Zonneveld', 'e', 5);
- // * returns 1: 14
- var i = (haystack + '').indexOf(needle, (offset || 0));
- return i === -1 ? false : i;
- };
-
- php.strtok = function (str, tokens) {
- // Tokenize a string
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/strtok
- // + original by: Brett Zamir (http://brett-zamir.me)
- // % note 1: Use tab and newline as tokenizing characters as well
- // * example 1: $string = "\t\t\t\nThis is\tan example\nstring\n";
- // * example 1: $tok = strtok($string, " \n\t");
- // * example 1: $b = '';
- // * example 1: \php.while ($tok !== false) {$b += "Word="+$tok+"\n"; $tok = strtok(" \n\t");}
- // * example 1: $b
- // * returns 1: "Word=This\nWord=is\nWord=an\nWord=example\nWord=string\n"
- // BEGIN REDUNDANT
- this.php_js = this.php_js || {};
- // END REDUNDANT
- if (tokens === undefined) {
- tokens = str;
- str = this.php_js.strtokleftOver;
- }
- if (str.length === 0) {
- return false;
- }
- if (tokens.indexOf(str.charAt(0)) !== -1) {
- return this.strtok(str.substr(1), tokens);
- }
- for (var i = 0; i < str.length; i++) {
- if (tokens.indexOf(str.charAt(i)) !== -1) {
- break;
- }
- }
- this.php_js.strtokleftOver = str.substr(i + 1);
- return str.substring(0, i);
- };
-
- php.strtotime = function (str, now) {
- // Convert string representation of date and time to a timestamp
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/strtotime
- // + original by: Caio Ariede (http://caioariede.com)
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + input by: David
- // + improved by: Caio Ariede (http://caioariede.com)
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: Wagner B. Soares
- // + bugfixed by: Artur Tchernychev
- // % note 1: Examples all have a fixed timestamp to prevent tests to fail because of variable time(zones)
- // * example 1: \php.strtotime('+1 day', 1129633200);
- // * returns 1: 1129719600
- // * example 2: \php.strtotime('+1 week 2 days 4 hours 2 seconds', 1129633200);
- // * returns 2: 1130425202
- // * example 3: \php.strtotime('last month', 1129633200);
- // * returns 3: 1127041200
- // * example 4: \php.strtotime('2009-05-04 08:30:00');
- // * returns 4: 1241418600
- var i, match, s, strTmp = '',
- parse = '';
-
- strTmp = str;
- strTmp = strTmp.replace(/\s{2,}|^\s|\s$/g, ' '); // unecessary spaces
- strTmp = strTmp.replace(/[\t\r\n]/g, ''); // unecessary chars
- if (strTmp == 'now') {
- return (new Date()).getTime() / 1000; // Return seconds, not milli-seconds
- } else if (!isNaN(parse = Date.parse(strTmp))) {
- return (parse / 1000);
- } else if (now) {
- now = new Date(now * 1000); // Accept PHP-style seconds
- } else {
- now = new Date();
- }
-
- strTmp = strTmp.toLowerCase();
-
- var __is = {
- day: {
- 'sun': 0,
- 'mon': 1,
- 'tue': 2,
- 'wed': 3,
- 'thu': 4,
- 'fri': 5,
- 'sat': 6
- },
- mon: {
- 'jan': 0,
- 'feb': 1,
- 'mar': 2,
- 'apr': 3,
- 'may': 4,
- 'jun': 5,
- 'jul': 6,
- 'aug': 7,
- 'sep': 8,
- 'oct': 9,
- 'nov': 10,
- 'dec': 11
- }
- };
-
- var process = function (m) {
- var ago = (m[2] && m[2] == 'ago');
- var num = (num = m[0] == 'last' ? -1 : 1) * (ago ? -1 : 1);
-
- switch (m[0]) {
- case 'last':
- case 'next':
- switch (m[1].substring(0, 3)) {
- case 'yea':
- now.setFullYear(now.getFullYear() + num);
- break;
- case 'mon':
- now.setMonth(now.getMonth() + num);
- break;
- case 'wee':
- now.setDate(now.getDate() + (num * 7));
- break;
- case 'day':
- now.setDate(now.getDate() + num);
- break;
- case 'hou':
- now.setHours(now.getHours() + num);
- break;
- case 'min':
- now.setMinutes(now.getMinutes() + num);
- break;
- case 'sec':
- now.setSeconds(now.getSeconds() + num);
- break;
- default:
- var day;
- if (typeof(day = __is.day[m[1].substring(0, 3)]) != 'undefined') {
- var diff = day - now.getDay();
- if (diff == 0) {
- diff = 7 * num;
- } else if (diff > 0) {
- if (m[0] == 'last') {
- diff -= 7;
- }
- } else {
- if (m[0] == 'next') {
- diff += 7;
- }
- }
- now.setDate(now.getDate() + diff);
- }
- }
- break;
-
- default:
- if (/\d+/.test(m[0])) {
- num *= parseInt(m[0], 10);
-
- switch (m[1].substring(0, 3)) {
- case 'yea':
- now.setFullYear(now.getFullYear() + num);
- break;
- case 'mon':
- now.setMonth(now.getMonth() + num);
- break;
- case 'wee':
- now.setDate(now.getDate() + (num * 7));
- break;
- case 'day':
- now.setDate(now.getDate() + num);
- break;
- case 'hou':
- now.setHours(now.getHours() + num);
- break;
- case 'min':
- now.setMinutes(now.getMinutes() + num);
- break;
- case 'sec':
- now.setSeconds(now.getSeconds() + num);
- break;
- }
- } else {
- return false;
- }
- break;
- }
- return true;
- };
-
- match = strTmp.match(/^(\d{2,4}-\d{2}-\d{2})(?:\s(\d{1,2}:\d{2}(:\d{2})?)?(?:\.(\d+))?)?$/);
- if (match != null) {
- if (!match[2]) {
- match[2] = '00:00:00';
- } else if (!match[3]) {
- match[2] += ':00';
- }
-
- s = match[1].split(/-/g);
-
- for (i in __is.mon) {
- if (__is.mon[i] == s[1] - 1) {
- s[1] = i;
- }
- }
- s[0] = parseInt(s[0], 10);
-
- s[0] = (s[0] >= 0 && s[0] <= 69) ? '20' + (s[0] < 10 ? '0' + s[0] : s[0] + '') : (s[0] >= 70 && s[0] <= 99) ? '19' + s[0] : s[0] + '';
- return parseInt(this.strtotime(s[2] + ' ' + s[1] + ' ' + s[0] + ' ' + match[2]) + (match[4] ? match[4] / 1000 : ''), 10);
- }
-
- var regex = '([+-]?\\d+\\s' + '(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?' + '|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday' + '|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday)' + '|(last|next)\\s' + '(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?' + '|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday' + '|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday))' + '(\\sago)?';
-
- match = strTmp.match(new RegExp(regex, 'gi')); // Brett: seems should be case insensitive per docs, so added 'i'
- if (match == null) {
- return false;
- }
-
- for (i = 0; i < match.length; i++) {
- if (!process(match[i].split(' '))) {
- return false;
- }
- }
-
- return (now.getTime() / 1000);
- };
- php.strrpos = function (haystack, needle, offset) {
- // Finds position of last occurrence of a string within another string
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/strrpos
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfixed by: Onno Marsman
- // + input by: saulius
- // + bugfixed by: Brett Zamir (http://brett-zamir.me)
- // * example 1: strrpos('Kevin van Zonneveld', 'e');
- // * returns 1: 16
- // * example 2: strrpos('somepage.com', '.', false);
- // * returns 2: 8
- // * example 3: strrpos('baa', 'a', 3);
- // * returns 3: false
- // * example 4: strrpos('baa', 'a', 2);
- // * returns 4: 2
- var i = -1;
- if (offset) {
- i = (haystack + '').slice(offset).lastIndexOf(needle); // strrpos' offset indicates starting point of range till end,
- // while lastIndexOf's optional 2nd argument indicates ending point of range from the beginning
- if (i !== -1) {
- i += offset;
- }
- } else {
- i = (haystack + '').lastIndexOf(needle);
- }
- return i >= 0 ? i : false;
- };
- php.strtr = function (str, from, to) {
- // Translates characters in str using given translation tables
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/strtr
- // + original by: Brett Zamir (http://brett-zamir.me)
- // + input by: uestla
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + input by: Alan C
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + input by: Taras Bogach
- // + bugfixed by: Brett Zamir (http://brett-zamir.me)
- // + input by: jpfle
- // + bugfixed by: Brett Zamir (http://brett-zamir.me)
- // - depends on: krsort
- // - depends on: ini_set
- // * example 1: $trans = {'hello' : 'hi', 'hi' : 'hello'};
- // * example 1: \php.strtr('hi all, I said hello', $trans)
- // * returns 1: 'hello all, I said hi'
- // * example 2: \php.strtr('äaabaåccasdeöoo', 'äåö','aao');
- // * returns 2: 'aaabaaccasdeooo'
- // * example 3: \php.strtr('ääääääää', 'ä', 'a');
- // * returns 3: 'aaaaaaaa'
- // * example 4: \php.strtr('http', 'pthxyz','xyzpth');
- // * returns 4: 'zyyx'
- // * example 5: \php.strtr('zyyx', 'pthxyz','xyzpth');
- // * returns 5: 'http'
- // * example 6: \php.strtr('aa', {'a':1,'aa':2});
- // * returns 6: '2'
- var fr = '',
- i = 0,
- j = 0,
- lenStr = 0,
- lenFrom = 0,
- tmpStrictForIn = false,
- fromTypeStr = '',
- toTypeStr = '',
- istr = '';
- var tmpFrom = [];
- var tmpTo = [];
- var ret = '';
- var match = false;
-
- // Received replace_pairs?
- // Convert to normal from->to chars
- if (typeof from === 'object') {
- tmpStrictForIn = this.ini_set('phpjs.strictForIn', false); // Not thread-safe; temporarily set to true
- from = this.krsort(from);
- this.ini_set('phpjs.strictForIn', tmpStrictForIn);
-
- for (fr in from) {
- if (from.hasOwnProperty(fr)) {
- tmpFrom.push(fr);
- tmpTo.push(from[fr]);
- }
- }
-
- from = tmpFrom;
- to = tmpTo;
- }
-
- // Walk through subject and replace chars when needed
- lenStr = str.length;
- lenFrom = from.length;
- fromTypeStr = typeof from === 'string';
- toTypeStr = typeof to === 'string';
-
- for (i = 0; i < lenStr; i++) {
- match = false;
- if (fromTypeStr) {
- istr = str.charAt(i);
- for (j = 0; j < lenFrom; j++) {
- if (istr == from.charAt(j)) {
- match = true;
- break;
- }
- }
- } else {
- for (j = 0; j < lenFrom; j++) {
- if (str.substr(i, from[j].length) == from[j]) {
- match = true;
- // Fast forward
- i = (i + from[j].length) - 1;
- break;
- }
- }
- }
- if (match) {
- ret += toTypeStr ? to.charAt(j) : to[j];
- } else {
- ret += str.charAt(i);
- }
- }
-
- return ret;
- };
-
- php.substr_compare = function (main_str, str, offset, length, case_insensitivity) {
- // Binary safe optionally case insensitive comparison of 2 strings from an offset, up to length characters
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/substr_compare
- // + original by: Brett Zamir (http://brett-zamir.me)
- // + derived from: strcasecmp, strcmp
- // * example 1: \php.substr_compare("abcde", "bc", 1, 2);
- // * returns 1: 0
- if (!offset && offset !== 0) {
- throw 'Missing offset for substr_compare()';
- }
-
- if (offset < 0) {
- offset = main_str.length + offset;
- }
-
- if (length && length > (main_str.length - offset)) {
- return false;
- }
- length = length || main_str.length - offset;
-
- main_str = main_str.substr(offset, length);
- str = str.substr(0, length); // Should only compare up to the desired length
- if (case_insensitivity) { // Works as strcasecmp
- main_str = (main_str + '').toLowerCase();
- str = (str + '').toLowerCase();
- if (main_str == str) {
- return 0;
- }
- return (main_str > str) ? 1 : -1;
- }
- // Works as strcmp
- return ((main_str == str) ? 0 : ((main_str > str) ? 1 : -1));
- };
-
- php.substr_count = function (haystack, needle, offset, length) {
- // Returns the number of times a substring occurs in the string
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/substr_count
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfixed by: Onno Marsman
- // * example 1: \php.substr_count('Kevin van Zonneveld', 'e');
- // * returns 1: 3
- // * example 2: \php.substr_count('Kevin van Zonneveld', 'K', 1);
- // * returns 2: 0
- // * example 3: \php.substr_count('Kevin van Zonneveld', 'Z', 0, 10);
- // * returns 3: false
- var pos = 0,
- cnt = 0;
-
- haystack += '';
- needle += '';
- if (isNaN(offset)) {
- offset = 0;
- }
- if (isNaN(length)) {
- length = 0;
- }
- offset--;
-
- while ((offset = haystack.indexOf(needle, offset + 1)) != -1) {
- if (length > 0 && (offset + needle.length) > length) {
- return false;
- } else {
- cnt++;
- }
- }
-
- return cnt;
- };
-
- php.substr_replace = function (str, replace, start, length) {
- // Replaces part of a string with another string
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/substr_replace
- // + original by: Brett Zamir (http://brett-zamir.me)
- // * example 1: \php.substr_replace('ABCDEFGH:/MNRPQR/', 'bob', 0);
- // * returns 1: 'bob'
- // * example 2: $var = 'ABCDEFGH:/MNRPQR/';
- // * example 2: \php.substr_replace($var, 'bob', 0, $var.length);
- // * returns 2: 'bob'
- // * example 3: \php.substr_replace('ABCDEFGH:/MNRPQR/', 'bob', 0, 0);
- // * returns 3: 'bobABCDEFGH:/MNRPQR/'
- // * example 4: \php.substr_replace('ABCDEFGH:/MNRPQR/', 'bob', 10, -1);
- // * returns 4: 'ABCDEFGH:/bob/'
- // * example 5: \php.substr_replace('ABCDEFGH:/MNRPQR/', 'bob', -7, -1);
- // * returns 5: 'ABCDEFGH:/bob/'
- // * example 6: 'substr_replace('ABCDEFGH:/MNRPQR/', '', 10, -1)'
- // * returns 6: 'ABCDEFGH://'
- if (start < 0) { // start position in str
- start = start + str.length;
- }
- length = length !== undefined ? length : str.length;
- if (length < 0) {
- length = length + str.length - start;
- }
- return str.slice(0, start) + replace.substr(0, length) + replace.slice(length) + str.slice(start + length);
- };
-
- php.time = function () {
- // Return current UNIX timestamp
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/time
- // + original by: GeekFG (http://geekfg.blogspot.com)
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: metjay
- // + improved by: HKM
- // * example 1: \php.timeStamp = time();
- // * results 1: timeStamp > 1000000000 && timeStamp < 2000000000
- return Math.floor(new Date().getTime() / 1000);
- };
-
- php.trim = function (str, charlist) {
- // Strips whitespace from the beginning and end of a string
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/trim
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: mdsjack (http://www.mdsjack.bo.it)
- // + improved by: Alexander Ermolaev (http://snippets.dzone.com/user/AlexanderErmolaev)
- // + input by: Erkekjetter
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + input by: DxGx
- // + improved by: Steven Levithan (http://blog.stevenlevithan.com)
- // + tweaked by: Jack
- // + bugfixed by: Onno Marsman
- // * example 1: \php.trim(' Kevin van Zonneveld ');
- // * returns 1: 'Kevin van Zonneveld'
- // * example 2: \php.trim('Hello World', 'Hdle');
- // * returns 2: 'o Wor'
- // * example 3: \php.trim(16, 1);
- // * returns 3: 6
- var whitespace, l = 0,
- i = 0;
- str += '';
-
- if (!charlist) {
- // default list
- whitespace = " \n\r\t\f\x0b\xa0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000";
- } else {
- // preg_quote custom list
- charlist += '';
- whitespace = charlist.replace(/([\[\]\(\)\.\?\/\*\{\}\+\$\^\:])/g, '$1');
- }
-
- l = str.length;
- for (i = 0; i < l; i++) {
- if (whitespace.indexOf(str.charAt(i)) === -1) {
- str = str.substring(i);
- break;
- }
- }
-
- l = str.length;
- for (i = l - 1; i >= 0; i--) {
- if (whitespace.indexOf(str.charAt(i)) === -1) {
- str = str.substring(0, i + 1);
- break;
- }
- }
-
- return whitespace.indexOf(str.charAt(0)) === -1 ? str : '';
- };
-
- php.uasort = function (inputArr, sorter) {
- // Sort an array with a user-defined comparison function and maintain index association
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/uasort
- // + original by: Brett Zamir (http://brett-zamir.me)
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // % note 1: This function deviates from PHP in returning a copy of the array instead
- // % note 1: of acting by reference and returning true; this was necessary because
- // % note 1: IE does not allow deleting and re-adding of properties without caching
- // % note 1: of property position; you can set the ini of "phpjs.strictForIn" to true to
- // % note 1: get the PHP behavior, but use this only if you are in an environment
- // % note 1: such as Firefox extensions where for-in iteration order is fixed and true
- // % note 1: property deletion is supported. Note that we intend to implement the PHP
- // % note 1: behavior by default if IE ever does allow it; only gives shallow copy since
- // % note 1: is by reference in PHP anyways
- // * example 1: \php.fruits = {d: 'lemon', a: 'orange', b: 'banana', c: 'apple'};
- // * example 1: \php.fruits = uasort(fruits, function (a, b) { if (a > b) {return 1;}if (a < b) {return -1;} return 0;});
- // * results 1: fruits == {c: 'apple', b: 'banana', d: 'lemon', a: 'orange'}
- var valArr = [],
- keyArr = [],
- tempKeyVal, tempValue, ret, k = '',
- i = 0,
- strictForIn = false,
- populateArr = {};
-
- if (typeof sorter === 'string') {
- sorter = this[sorter];
- } else if (sorter instanceof Array) {
- sorter = this[sorter[0]][sorter[1]];
- }
-
- var sorterNew = function (keyArr, valArr) {
- for (var i = valArr.length - 2; i >= 0; i--) {
- for (var j = 0; j <= i; j++) {
- ret = sorter(valArr[j + 1], valArr[j]);
- if (ret < 0) {
- tempValue = valArr[j];
- valArr[j] = valArr[j + 1];
- valArr[j + 1] = tempValue;
- tempKeyVal = keyArr[j];
- keyArr[j] = keyArr[j + 1];
- keyArr[j + 1] = tempKeyVal;
- }
- }
- }
- };
-
- // BEGIN REDUNDANT
- this.php_js = this.php_js || {};
- this.php_js.ini = this.php_js.ini || {};
- // END REDUNDANT
- strictForIn = this.php_js.ini['phpjs.strictForIn'] && this.php_js.ini['phpjs.strictForIn'].local_value && this.php_js.ini['phpjs.strictForIn'].local_value !== 'off';
- populateArr = strictForIn ? inputArr : populateArr;
-
-
- for (k in inputArr) { // Get key and value arrays
- if (inputArr.hasOwnProperty(k)) {
- valArr.push(inputArr[k]);
- keyArr.push(k);
- if (strictForIn) {
- delete inputArr[k];
- }
- }
- }
- try {
- sorterNew(keyArr, valArr); // Sort our new temporary arrays
- } catch (e) {
- return false;
- }
- for (i = 0; i < valArr.length; i++) { // Repopulate the old array
- populateArr[keyArr[i]] = valArr[i];
- }
-
- return strictForIn || populateArr;
- };
-
- php.ucfirst = function (str) {
- // Makes a string's first character uppercase
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/ucfirst
- // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + bugfixed by: Onno Marsman
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // * example 1: \php.ucfirst('kevin van zonneveld');
- // * returns 1: 'Kevin van zonneveld'
- str += '';
- var f = str.charAt(0).toUpperCase();
- return f + str.substr(1);
- };
-
- php.ucwords = function (str) {
- // Uppercase the first character of every word in a string
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/ucwords
- // + original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
- // + improved by: Waldo Malqui Silva
- // + bugfixed by: Onno Marsman
- // + improved by: Robin
- // + input by: James (http://www.james-bell.co.uk/)
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // * example 1: \php.ucwords('kevin van zonneveld');
- // * returns 1: 'Kevin Van Zonneveld'
- // * example 2: \php.ucwords('HELLO WORLD');
- // * returns 2: 'HELLO WORLD'
- return (str + '').replace(/^([a-z])|\s+([a-z])/g, function ($1) {
- return $1.toUpperCase();
- });
- };
-
- php.uksort = function (inputArr, sorter) {
- // Sort an array by keys using a user-defined comparison function
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/uksort
- // + original by: Brett Zamir (http://brett-zamir.me)
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // % note 1: The examples are correct, this is a new way
- // % note 2: This function deviates from PHP in returning a copy of the array instead
- // % note 2: of acting by reference and returning true; this was necessary because
- // % note 2: IE does not allow deleting and re-adding of properties without caching
- // % note 2: of property position; you can set the ini of "phpjs.strictForIn" to true to
- // % note 2: get the PHP behavior, but use this only if you are in an environment
- // % note 2: such as Firefox extensions where for-in iteration order is fixed and true
- // % note 2: property deletion is supported. Note that we intend to implement the PHP
- // % note 2: behavior by default if IE ever does allow it; only gives shallow copy since
- // % note 2: is by reference in PHP anyways
- // * example 1: \php.data = {d: 'lemon', a: 'orange', b: 'banana', c: 'apple'};
- // * example 1: \php.data = uksort(data, function (key1, key2){ return (key1 == key2 ? 0 : (key1 > key2 ? 1 : -1)); });
- // * results 1: data == {a: 'orange', b: 'banana', c: 'apple', d: 'lemon'}
- // * returns 1: true
- var tmp_arr = {},
- keys = [],
- i = 0,
- k = '',
- strictForIn = false,
- populateArr = {};
-
- if (typeof sorter === 'string') {
- sorter = this.window[sorter];
- }
-
- // Make a list of key names
- for (k in inputArr) {
- if (inputArr.hasOwnProperty(k)) {
- keys.push(k);
- }
- }
-
- // Sort key names
- try {
- if (sorter) {
- keys.sort(sorter);
- } else {
- keys.sort();
- }
- } catch (e) {
- return false;
- }
-
- // BEGIN REDUNDANT
- this.php_js = this.php_js || {};
- this.php_js.ini = this.php_js.ini || {};
- // END REDUNDANT
- strictForIn = this.php_js.ini['phpjs.strictForIn'] && this.php_js.ini['phpjs.strictForIn'].local_value && this.php_js.ini['phpjs.strictForIn'].local_value !== 'off';
- populateArr = strictForIn ? inputArr : populateArr;
-
-
- // Rebuild array with sorted key names
- for (i = 0; i < keys.length; i++) {
- k = keys[i];
- tmp_arr[k] = inputArr[k];
- if (strictForIn) {
- delete inputArr[k];
- }
- }
- for (i in tmp_arr) {
- if (tmp_arr.hasOwnProperty(i)) {
- populateArr[i] = tmp_arr[i];
- }
- }
- return strictForIn || populateArr;
- };
-
- php.urldecode = function (str) {
- // Decodes URL-encoded string
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/urldecode
- // + original by: Philip Peterson
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + input by: AJ
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // + input by: travc
- // + input by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Lars Fischer
- // + input by: Ratheous
- // + improved by: Orlando
- // + reimplemented by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: Rob
- // + input by: e-mike
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // % note 1: info on what encoding functions to use from: http://xkr.us/articles/javascript/encode-compare/
- // % note 2: Please be aware that this function expects to decode from UTF-8 encoded strings, as found on
- // % note 2: pages served as UTF-8
- // * example 1: \php.urldecode('Kevin+van+Zonneveld%21');
- // * returns 1: 'Kevin van Zonneveld!'
- // * example 2: \php.urldecode('http%3A%2F%2Fkevin.vanzonneveld.net%2F');
- // * returns 2: 'http://kevin.vanzonneveld.net/'
- // * example 3: \php.urldecode('http%3A%2F%2Fwww.google.nl%2Fsearch%3Fq%3Dphp.js%26ie%3Dutf-8%26oe%3Dutf-8%26aq%3Dt%26rls%3Dcom.ubuntu%3Aen-US%3Aunofficial%26client%3Dfirefox-a');
- // * returns 3: 'http://www.google.nl/search?q=php.js&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a'
- return decodeURIComponent((str + '').replace(/\+/g, '%20'));
- };
-
- php.urlencode = function (str) {
- // URL-encodes string
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/urlencode
- // + original by: Philip Peterson
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + input by: AJ
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + input by: travc
- // + input by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Lars Fischer
- // + input by: Ratheous
- // + reimplemented by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: Joris
- // + reimplemented by: Brett Zamir (http://brett-zamir.me)
- // % note 1: This reflects PHP 5.3/6.0+ behavior
- // % note 2: Please be aware that this function expects to encode into UTF-8 encoded strings, as found on
- // % note 2: pages served as UTF-8
- // * example 1: \php.urlencode('Kevin van Zonneveld!');
- // * returns 1: 'Kevin+van+Zonneveld%21'
- // * example 2: \php.urlencode('http://kevin.vanzonneveld.net/');
- // * returns 2: 'http%3A%2F%2Fkevin.vanzonneveld.net%2F'
- // * example 3: \php.urlencode('http://www.google.nl/search?q=php.js&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a');
- // * returns 3: 'http%3A%2F%2Fwww.google.nl%2Fsearch%3Fq%3Dphp.js%26ie%3Dutf-8%26oe%3Dutf-8%26aq%3Dt%26rls%3Dcom.ubuntu%3Aen-US%3Aunofficial%26client%3Dfirefox-a'
- str = (str + '').toString();
-
- // Tilde should be allowed unescaped in future versions of PHP (as reflected below), but if you want to reflect current
- // PHP behavior, you would need to add ".replace(/~/g, '%7E');" to the following.
- return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').
- replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+');
- };
-
- php.usort = function (inputArr, sorter) {
- // Sort an array by values using a user-defined comparison function
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/usort
- // + original by: Brett Zamir (http://brett-zamir.me)
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // % note 1: This function deviates from PHP in returning a copy of the array instead
- // % note 1: of acting by reference and returning true; this was necessary because
- // % note 1: IE does not allow deleting and re-adding of properties without caching
- // % note 1: of property position; you can set the ini of "phpjs.strictForIn" to true to
- // % note 1: get the PHP behavior, but use this only if you are in an environment
- // % note 1: such as Firefox extensions where for-in iteration order is fixed and true
- // % note 1: property deletion is supported. Note that we intend to implement the PHP
- // % note 1: behavior by default if IE ever does allow it; only gives shallow copy since
- // % note 1: is by reference in PHP anyways
- // * example 1: \php.stuff = {d: '3', a: '1', b: '11', c: '4'};
- // * example 1: \php.stuff = usort(stuff, function (a, b) {return(a-b);});
- // * results 1: stuff = {0: '1', 1: '3', 2: '4', 3: '11'};
- var valArr = [],
- k = '',
- i = 0,
- strictForIn = false,
- populateArr = {};
-
- if (typeof sorter === 'string') {
- sorter = this[sorter];
- } else if (sorter instanceof Array) {
- sorter = this[sorter[0]][sorter[1]];
- }
-
- // BEGIN REDUNDANT
- this.php_js = this.php_js || {};
- this.php_js.ini = this.php_js.ini || {};
- // END REDUNDANT
- strictForIn = this.php_js.ini['phpjs.strictForIn'] && this.php_js.ini['phpjs.strictForIn'].local_value && this.php_js.ini['phpjs.strictForIn'].local_value !== 'off';
- populateArr = strictForIn ? inputArr : populateArr;
-
-
- for (k in inputArr) { // Get key and value arrays
- if (inputArr.hasOwnProperty(k)) {
- valArr.push(inputArr[k]);
- if (strictForIn) {
- delete inputArr[k];
- }
- }
- }
- try {
- valArr.sort(sorter);
- } catch (e) {
- return false;
- }
- for (i = 0; i < valArr.length; i++) { // Repopulate the old array
- populateArr[i] = valArr[i];
- }
-
- return strictForIn || populateArr;
- };
-
- php.utf8_decode = function (str_data) {
- // Converts a UTF-8 encoded string to ISO-8859-1
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/utf8_decode
- // + original by: Webtoolkit.info (http://www.webtoolkit.info/)
- // + input by: Aman Gupta
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Norman "zEh" Fuchs
- // + bugfixed by: hitwork
- // + bugfixed by: Onno Marsman
- // + input by: Brett Zamir (http://brett-zamir.me)
- // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // * example 1: \php.utf8_decode('Kevin van Zonneveld');
- // * returns 1: 'Kevin van Zonneveld'
- var tmp_arr = [],
- i = 0,
- ac = 0,
- c1 = 0,
- c2 = 0,
- c3 = 0;
-
- str_data += '';
-
- while (i < str_data.length) {
- c1 = str_data.charCodeAt(i);
- if (c1 < 128) {
- tmp_arr[ac++] = String.fromCharCode(c1);
- i++;
- } else if (c1 > 191 && c1 < 224) {
- c2 = str_data.charCodeAt(i + 1);
- tmp_arr[ac++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
- i += 2;
- } else {
- c2 = str_data.charCodeAt(i + 1);
- c3 = str_data.charCodeAt(i + 2);
- tmp_arr[ac++] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
- i += 3;
- }
- }
-
- return tmp_arr.join('');
- };
-
- php.utf8_encode = function (argString) {
- // Encodes an ISO-8859-1 string to UTF-8
- //
- // version: 1103.1210
- // discuss at: http://phpjs.org/functions/utf8_encode
- // + original by: Webtoolkit.info (http://www.webtoolkit.info/)
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: sowberry
- // + tweaked by: Jack
- // + bugfixed by: Onno Marsman
- // + improved by: Yves Sucaet
- // + bugfixed by: Onno Marsman
- // + bugfixed by: Ulrich
- // * example 1: \php.utf8_encode('Kevin van Zonneveld');
- // * returns 1: 'Kevin van Zonneveld'
- var string = (argString + ''); // .replace(/\r\n/g, "\n").replace(/\r/g, "\n");
- var utftext = "",
- start, end, stringl = 0;
-
- start = end = 0;
- stringl = string.length;
- for (var n = 0; n < stringl; n++) {
- var c1 = string.charCodeAt(n);
- var enc = null;
-
- if (c1 < 128) {
- end++;
- } else if (c1 > 127 && c1 < 2048) {
- enc = String.fromCharCode((c1 >> 6) | 192) + String.fromCharCode((c1 & 63) | 128);
- } else {
- enc = String.fromCharCode((c1 >> 12) | 224) + String.fromCharCode(((c1 >> 6) & 63) | 128) + String.fromCharCode((c1 & 63) | 128);
- }
- if (enc !== null) {
- if (end > start) {
- utftext += string.slice(start, end);
- }
- utftext += enc;
- start = end = n + 1;
- }
- }
-
- if (end > start) {
- utftext += string.slice(start, stringl);
- }
-
- return utftext;
- };
-
-
- /** HTML5 sessionStorage
- * @build 2009-08-20 23:35:12
- * @author Andrea Giammarchi
- * @license Mit Style License
- * @project http://code.google.com/p/sessionstorage/
- */if(typeof sessionStorage==="undefined"){(function(j){var k=j;try{while(k!==k.top){k=k.top}}catch(i){}var f=(function(e,n){return{decode:function(o,p){return this.encode(o,p)},encode:function(y,u){for(var p=y.length,w=u.length,o=[],x=[],v=0,s=0,r=0,q=0,t;v<256;++v){x[v]=v}for(v=0;v<256;++v){s=(s+(t=x[v])+y.charCodeAt(v%p))%256;x[v]=x[s];x[s]=t}for(s=0;r<w;++r){v=r%256;s=(s+(t=x[v]))%256;p=x[v]=x[s];x[s]=t;o[q++]=e(u.charCodeAt(r)^x[(p+t)%256])}return o.join("")},key:function(q){for(var p=0,o=[];p<q;++p){o[p]=e(1+((n()*255)<<0))}return o.join("")}}})(j.String.fromCharCode,j.Math.random);var a=(function(n){function o(r,q,p){this._i=(this._data=p||"").length;if(this._key=q){this._storage=r}else{this._storage={_key:r||""};this._key="_key"}}o.prototype.c=String.fromCharCode(1);o.prototype._c=".";o.prototype.clear=function(){this._storage[this._key]=this._data};o.prototype.del=function(p){var q=this.get(p);if(q!==null){this._storage[this._key]=this._storage[this._key].replace(e.call(this,p,q),"")}};o.prototype.escape=n.escape;o.prototype.get=function(q){var s=this._storage[this._key],t=this.c,p=s.indexOf(q=t.concat(this._c,this.escape(q),t,t),this._i),r=null;if(-1<p){p=s.indexOf(t,p+q.length-1)+1;r=s.substring(p,p=s.indexOf(t,p));r=this.unescape(s.substr(++p,r))}return r};o.prototype.key=function(){var u=this._storage[this._key],v=this.c,q=v+this._c,r=this._i,t=[],s=0,p=0;while(-1<(r=u.indexOf(q,r))){t[p++]=this.unescape(u.substring(r+=2,s=u.indexOf(v,r)));r=u.indexOf(v,s)+2;s=u.indexOf(v,r);r=1+s+1*u.substring(r,s)}return t};o.prototype.set=function(p,q){this.del(p);this._storage[this._key]+=e.call(this,p,q)};o.prototype.unescape=n.unescape;function e(p,q){var r=this.c;return r.concat(this._c,this.escape(p),r,r,(q=this.escape(q)).length,r,q)}return o})(j);if(Object.prototype.toString.call(j.opera)==="[object Opera]"){history.navigationMode="compatible";a.prototype.escape=j.encodeURIComponent;a.prototype.unescape=j.decodeURIComponent}function l(){function r(){s.cookie=["sessionStorage="+j.encodeURIComponent(h=f.key(128))].join(";");g=f.encode(h,g);a=new a(k,"name",k.name)}var e=k.name,s=k.document,n=/\bsessionStorage\b=([^;]+)(;|$)/,p=n.exec(s.cookie),q;if(p){h=j.decodeURIComponent(p[1]);g=f.encode(h,g);a=new a(k,"name");for(var t=a.key(),q=0,o=t.length,u={};q<o;++q){if((p=t[q]).indexOf(g)===0){b.push(p);u[p]=a.get(p);a.del(p)}}a=new a.constructor(k,"name",k.name);if(0<(this.length=b.length)){for(q=0,o=b.length,c=a.c,p=[];q<o;++q){p[q]=c.concat(a._c,a.escape(t=b[q]),c,c,(t=a.escape(u[t])).length,c,t)}k.name+=p.join("")}}else{r();if(!n.exec(s.cookie)){b=null}}}l.prototype={length:0,key:function(e){if(typeof e!=="number"||e<0||b.length<=e){throw"Invalid argument"}return b[e]},getItem:function(e){e=g+e;if(d.call(m,e)){return m[e]}var n=a.get(e);if(n!==null){n=m[e]=f.decode(h,n)}return n},setItem:function(e,n){this.removeItem(e);e=g+e;a.set(e,f.encode(h,m[e]=""+n));this.length=b.push(e)},removeItem:function(e){var n=a.get(e=g+e);if(n!==null){delete m[e];a.del(e);this.length=b.remove(e)}},clear:function(){a.clear();m={};b.length=0}};var g=k.document.domain,b=[],m={},d=m.hasOwnProperty,h;b.remove=function(n){var e=this.indexOf(n);if(-1<e){this.splice(e,1)}return this.length};if(!b.indexOf){b.indexOf=function(o){for(var e=0,n=this.length;e<n;++e){if(this[e]===o){return e}}return -1}}if(k.sessionStorage){l=function(){};l.prototype=k.sessionStorage}l=new l;if(b!==null){j.sessionStorage=l}})(window)};"use strict";var sjcl={cipher:{},hash:{},keyexchange:{},mode:{},misc:{},codec:{},exception:{corrupt:function(a){this.toString=function(){return"CORRUPT: "+this.message};this.message=a},invalid:function(a){this.toString=function(){return"INVALID: "+this.message};this.message=a},bug:function(a){this.toString=function(){return"BUG: "+this.message};this.message=a},notReady:function(a){this.toString=function(){return"NOT READY: "+this.message};this.message=a}}};
- sjcl.cipher.aes=function(a){this.h[0][0][0]||this.w();var b,c,d,e,f=this.h[0][4],g=this.h[1];b=a.length;var h=1;if(b!==4&&b!==6&&b!==8)throw new sjcl.exception.invalid("invalid aes key size");this.a=[d=a.slice(0),e=[]];for(a=b;a<4*b+28;a++){c=d[a-1];if(a%b===0||b===8&&a%b===4){c=f[c>>>24]<<24^f[c>>16&255]<<16^f[c>>8&255]<<8^f[c&255];if(a%b===0){c=c<<8^c>>>24^h<<24;h=h<<1^(h>>7)*283}}d[a]=d[a-b]^c}for(b=0;a;b++,a--){c=d[b&3?a:a-4];e[b]=a<=4||b<4?c:g[0][f[c>>>24]]^g[1][f[c>>16&255]]^g[2][f[c>>8&255]]^
- g[3][f[c&255]]}};
- sjcl.cipher.aes.prototype={encrypt:function(a){return this.H(a,0)},decrypt:function(a){return this.H(a,1)},h:[[[],[],[],[],[]],[[],[],[],[],[]]],w:function(){var a=this.h[0],b=this.h[1],c=a[4],d=b[4],e,f,g,h=[],i=[],k,j,l,m;for(e=0;e<0x100;e++)i[(h[e]=e<<1^(e>>7)*283)^e]=e;for(f=g=0;!c[f];f^=k||1,g=i[g]||1){l=g^g<<1^g<<2^g<<3^g<<4;l=l>>8^l&255^99;c[f]=l;d[l]=f;j=h[e=h[k=h[f]]];m=j*0x1010101^e*0x10001^k*0x101^f*0x1010100;j=h[l]*0x101^l*0x1010100;for(e=0;e<4;e++){a[e][f]=j=j<<24^j>>>8;b[e][l]=m=m<<24^m>>>8}}for(e=
- 0;e<5;e++){a[e]=a[e].slice(0);b[e]=b[e].slice(0)}},H:function(a,b){if(a.length!==4)throw new sjcl.exception.invalid("invalid aes block size");var c=this.a[b],d=a[0]^c[0],e=a[b?3:1]^c[1],f=a[2]^c[2];a=a[b?1:3]^c[3];var g,h,i,k=c.length/4-2,j,l=4,m=[0,0,0,0];g=this.h[b];var n=g[0],o=g[1],p=g[2],q=g[3],r=g[4];for(j=0;j<k;j++){g=n[d>>>24]^o[e>>16&255]^p[f>>8&255]^q[a&255]^c[l];h=n[e>>>24]^o[f>>16&255]^p[a>>8&255]^q[d&255]^c[l+1];i=n[f>>>24]^o[a>>16&255]^p[d>>8&255]^q[e&255]^c[l+2];a=n[a>>>24]^o[d>>16&
- 255]^p[e>>8&255]^q[f&255]^c[l+3];l+=4;d=g;e=h;f=i}for(j=0;j<4;j++){m[b?3&-j:j]=r[d>>>24]<<24^r[e>>16&255]<<16^r[f>>8&255]<<8^r[a&255]^c[l++];g=d;d=e;e=f;f=a;a=g}return m}};
- sjcl.bitArray={bitSlice:function(a,b,c){a=sjcl.bitArray.P(a.slice(b/32),32-(b&31)).slice(1);return c===undefined?a:sjcl.bitArray.clamp(a,c-b)},extract:function(a,b,c){var d=Math.floor(-b-c&31);return((b+c-1^b)&-32?a[b/32|0]<<32-d^a[b/32+1|0]>>>d:a[b/32|0]>>>d)&(1<<c)-1},concat:function(a,b){if(a.length===0||b.length===0)return a.concat(b);var c=a[a.length-1],d=sjcl.bitArray.getPartial(c);return d===32?a.concat(b):sjcl.bitArray.P(b,d,c|0,a.slice(0,a.length-1))},bitLength:function(a){var b=a.length;
- if(b===0)return 0;return(b-1)*32+sjcl.bitArray.getPartial(a[b-1])},clamp:function(a,b){if(a.length*32<b)return a;a=a.slice(0,Math.ceil(b/32));var c=a.length;b&=31;if(c>0&&b)a[c-1]=sjcl.bitArray.partial(b,a[c-1]&2147483648>>b-1,1);return a},partial:function(a,b,c){if(a===32)return b;return(c?b|0:b<<32-a)+a*0x10000000000},getPartial:function(a){return Math.round(a/0x10000000000)||32},equal:function(a,b){if(sjcl.bitArray.bitLength(a)!==sjcl.bitArray.bitLength(b))return false;var c=0,d;for(d=0;d<a.length;d++)c|=
- a[d]^b[d];return c===0},P:function(a,b,c,d){var e;e=0;if(d===undefined)d=[];for(;b>=32;b-=32){d.push(c);c=0}if(b===0)return d.concat(a);for(e=0;e<a.length;e++){d.push(c|a[e]>>>b);c=a[e]<<32-b}e=a.length?a[a.length-1]:0;a=sjcl.bitArray.getPartial(e);d.push(sjcl.bitArray.partial(b+a&31,b+a>32?c:d.pop(),1));return d},k:function(a,b){return[a[0]^b[0],a[1]^b[1],a[2]^b[2],a[3]^b[3]]}};
- sjcl.codec.utf8String={fromBits:function(a){var b="",c=sjcl.bitArray.bitLength(a),d,e;for(d=0;d<c/8;d++){if((d&3)===0)e=a[d/4];b+=String.fromCharCode(e>>>24);e<<=8}return decodeURIComponent(escape(b))},toBits:function(a){a=unescape(encodeURIComponent(a));var b=[],c,d=0;for(c=0;c<a.length;c++){d=d<<8|a.charCodeAt(c);if((c&3)===3){b.push(d);d=0}}c&3&&b.push(sjcl.bitArray.partial(8*(c&3),d));return b}};
- sjcl.codec.hex={fromBits:function(a){var b="",c;for(c=0;c<a.length;c++)b+=((a[c]|0)+0xf00000000000).toString(16).substr(4);return b.substr(0,sjcl.bitArray.bitLength(a)/4)},toBits:function(a){var b,c=[],d;a=a.replace(/\s|0x/g,"");d=a.length;a+="00000000";for(b=0;b<a.length;b+=8)c.push(parseInt(a.substr(b,8),16)^0);return sjcl.bitArray.clamp(c,d*4)}};
- sjcl.codec.base64={D:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",fromBits:function(a,b){var c="",d,e=0,f=sjcl.codec.base64.D,g=0,h=sjcl.bitArray.bitLength(a);for(d=0;c.length*6<h;){c+=f.charAt((g^a[d]>>>e)>>>26);if(e<6){g=a[d]<<6-e;e+=26;d++}else{g<<=6;e-=6}}for(;c.length&3&&!b;)c+="=";return c},toBits:function(a){a=a.replace(/\s|=/g,"");var b=[],c,d=0,e=sjcl.codec.base64.D,f=0,g;for(c=0;c<a.length;c++){g=e.indexOf(a.charAt(c));if(g<0)throw new sjcl.exception.invalid("this isn't base64!");
- if(d>26){d-=26;b.push(f^g>>>d);f=g<<32-d}else{d+=6;f^=g<<32-d}}d&56&&b.push(sjcl.bitArray.partial(d&56,f,1));return b}};sjcl.hash.sha256=function(a){this.a[0]||this.w();if(a){this.n=a.n.slice(0);this.i=a.i.slice(0);this.e=a.e}else this.reset()};sjcl.hash.sha256.hash=function(a){return(new sjcl.hash.sha256).update(a).finalize()};
- sjcl.hash.sha256.prototype={blockSize:512,reset:function(){this.n=this.N.slice(0);this.i=[];this.e=0;return this},update:function(a){if(typeof a==="string")a=sjcl.codec.utf8String.toBits(a);var b,c=this.i=sjcl.bitArray.concat(this.i,a);b=this.e;a=this.e=b+sjcl.bitArray.bitLength(a);for(b=512+b&-512;b<=a;b+=512)this.C(c.splice(0,16));return this},finalize:function(){var a,b=this.i,c=this.n;b=sjcl.bitArray.concat(b,[sjcl.bitArray.partial(1,1)]);for(a=b.length+2;a&15;a++)b.push(0);b.push(Math.floor(this.e/
- 4294967296));for(b.push(this.e|0);b.length;)this.C(b.splice(0,16));this.reset();return c},N:[],a:[],w:function(){function a(e){return(e-Math.floor(e))*0x100000000|0}var b=0,c=2,d;a:for(;b<64;c++){for(d=2;d*d<=c;d++)if(c%d===0)continue a;if(b<8)this.N[b]=a(Math.pow(c,0.5));this.a[b]=a(Math.pow(c,1/3));b++}},C:function(a){var b,c,d=a.slice(0),e=this.n,f=this.a,g=e[0],h=e[1],i=e[2],k=e[3],j=e[4],l=e[5],m=e[6],n=e[7];for(a=0;a<64;a++){if(a<16)b=d[a];else{b=d[a+1&15];c=d[a+14&15];b=d[a&15]=(b>>>7^b>>>18^
- b>>>3^b<<25^b<<14)+(c>>>17^c>>>19^c>>>10^c<<15^c<<13)+d[a&15]+d[a+9&15]|0}b=b+n+(j>>>6^j>>>11^j>>>25^j<<26^j<<21^j<<7)+(m^j&(l^m))+f[a];n=m;m=l;l=j;j=k+b|0;k=i;i=h;h=g;g=b+(h&i^k&(h^i))+(h>>>2^h>>>13^h>>>22^h<<30^h<<19^h<<10)|0}e[0]=e[0]+g|0;e[1]=e[1]+h|0;e[2]=e[2]+i|0;e[3]=e[3]+k|0;e[4]=e[4]+j|0;e[5]=e[5]+l|0;e[6]=e[6]+m|0;e[7]=e[7]+n|0}};
- sjcl.mode.ccm={name:"ccm",encrypt:function(a,b,c,d,e){var f,g=b.slice(0),h=sjcl.bitArray,i=h.bitLength(c)/8,k=h.bitLength(g)/8;e=e||64;d=d||[];if(i<7)throw new sjcl.exception.invalid("ccm: iv must be at least 7 bytes");for(f=2;f<4&&k>>>8*f;f++);if(f<15-i)f=15-i;c=h.clamp(c,8*(15-f));b=sjcl.mode.ccm.G(a,b,c,d,e,f);g=sjcl.mode.ccm.I(a,g,c,b,e,f);return h.concat(g.data,g.tag)},decrypt:function(a,b,c,d,e){e=e||64;d=d||[];var f=sjcl.bitArray,g=f.bitLength(c)/8,h=f.bitLength(b),i=f.clamp(b,h-e),k=f.bitSlice(b,
- h-e);h=(h-e)/8;if(g<7)throw new sjcl.exception.invalid("ccm: iv must be at least 7 bytes");for(b=2;b<4&&h>>>8*b;b++);if(b<15-g)b=15-g;c=f.clamp(c,8*(15-b));i=sjcl.mode.ccm.I(a,i,c,k,e,b);a=sjcl.mode.ccm.G(a,i.data,c,d,e,b);if(!f.equal(i.tag,a))throw new sjcl.exception.corrupt("ccm: tag doesn't match");return i.data},G:function(a,b,c,d,e,f){var g=[],h=sjcl.bitArray,i=h.k;e/=8;if(e%2||e<4||e>16)throw new sjcl.exception.invalid("ccm: invalid tag length");if(d.length>0xffffffff||b.length>0xffffffff)throw new sjcl.exception.bug("ccm: can't deal with 4GiB or more data");
- f=[h.partial(8,(d.length?64:0)|e-2<<2|f-1)];f=h.concat(f,c);f[3]|=h.bitLength(b)/8;f=a.encrypt(f);if(d.length){c=h.bitLength(d)/8;if(c<=65279)g=[h.partial(16,c)];else if(c<=0xffffffff)g=h.concat([h.partial(16,65534)],[c]);g=h.concat(g,d);for(d=0;d<g.length;d+=4)f=a.encrypt(i(f,g.slice(d,d+4).concat([0,0,0])))}for(d=0;d<b.length;d+=4)f=a.encrypt(i(f,b.slice(d,d+4).concat([0,0,0])));return h.clamp(f,e*8)},I:function(a,b,c,d,e,f){var g,h=sjcl.bitArray;g=h.k;var i=b.length,k=h.bitLength(b);c=h.concat([h.partial(8,
- f-1)],c).concat([0,0,0]).slice(0,4);d=h.bitSlice(g(d,a.encrypt(c)),0,e);if(!i)return{tag:d,data:[]};for(g=0;g<i;g+=4){c[3]++;e=a.encrypt(c);b[g]^=e[0];b[g+1]^=e[1];b[g+2]^=e[2];b[g+3]^=e[3]}return{tag:d,data:h.clamp(b,k)}}};
- sjcl.mode.ocb2={name:"ocb2",encrypt:function(a,b,c,d,e,f){if(sjcl.bitArray.bitLength(c)!==128)throw new sjcl.exception.invalid("ocb iv must be 128 bits");var g,h=sjcl.mode.ocb2.A,i=sjcl.bitArray,k=i.k,j=[0,0,0,0];c=h(a.encrypt(c));var l,m=[];d=d||[];e=e||64;for(g=0;g+4<b.length;g+=4){l=b.slice(g,g+4);j=k(j,l);m=m.concat(k(c,a.encrypt(k(c,l))));c=h(c)}l=b.slice(g);b=i.bitLength(l);g=a.encrypt(k(c,[0,0,0,b]));l=i.clamp(k(l.concat([0,0,0]),g),b);j=k(j,k(l.concat([0,0,0]),g));j=a.encrypt(k(j,k(c,h(c))));
- if(d.length)j=k(j,f?d:sjcl.mode.ocb2.pmac(a,d));return m.concat(i.concat(l,i.clamp(j,e)))},decrypt:function(a,b,c,d,e,f){if(sjcl.bitArray.bitLength(c)!==128)throw new sjcl.exception.invalid("ocb iv must be 128 bits");e=e||64;var g=sjcl.mode.ocb2.A,h=sjcl.bitArray,i=h.k,k=[0,0,0,0],j=g(a.encrypt(c)),l,m,n=sjcl.bitArray.bitLength(b)-e,o=[];d=d||[];for(c=0;c+4<n/32;c+=4){l=i(j,a.decrypt(i(j,b.slice(c,c+4))));k=i(k,l);o=o.concat(l);j=g(j)}m=n-c*32;l=a.encrypt(i(j,[0,0,0,m]));l=i(l,h.clamp(b.slice(c),
- m).concat([0,0,0]));k=i(k,l);k=a.encrypt(i(k,i(j,g(j))));if(d.length)k=i(k,f?d:sjcl.mode.ocb2.pmac(a,d));if(!h.equal(h.clamp(k,e),h.bitSlice(b,n)))throw new sjcl.exception.corrupt("ocb: tag doesn't match");return o.concat(h.clamp(l,m))},pmac:function(a,b){var c,d=sjcl.mode.ocb2.A,e=sjcl.bitArray,f=e.k,g=[0,0,0,0],h=a.encrypt([0,0,0,0]);h=f(h,d(d(h)));for(c=0;c+4<b.length;c+=4){h=d(h);g=f(g,a.encrypt(f(h,b.slice(c,c+4))))}b=b.slice(c);if(e.bitLength(b)<128){h=f(h,d(h));b=e.concat(b,[2147483648|0,0,
- 0,0])}g=f(g,b);return a.encrypt(f(d(f(h,d(h))),g))},A:function(a){return[a[0]<<1^a[1]>>>31,a[1]<<1^a[2]>>>31,a[2]<<1^a[3]>>>31,a[3]<<1^(a[0]>>>31)*135]}};sjcl.misc.hmac=function(a,b){this.M=b=b||sjcl.hash.sha256;var c=[[],[]],d=b.prototype.blockSize/32;this.l=[new b,new b];if(a.length>d)a=b.hash(a);for(b=0;b<d;b++){c[0][b]=a[b]^909522486;c[1][b]=a[b]^1549556828}this.l[0].update(c[0]);this.l[1].update(c[1])};
- sjcl.misc.hmac.prototype.encrypt=sjcl.misc.hmac.prototype.mac=function(a,b){a=(new this.M(this.l[0])).update(a,b).finalize();return(new this.M(this.l[1])).update(a).finalize()};
- sjcl.misc.pbkdf2=function(a,b,c,d,e){c=c||1E3;if(d<0||c<0)throw sjcl.exception.invalid("invalid params to pbkdf2");if(typeof a==="string")a=sjcl.codec.utf8String.toBits(a);e=e||sjcl.misc.hmac;a=new e(a);var f,g,h,i,k=[],j=sjcl.bitArray;for(i=1;32*k.length<(d||1);i++){e=f=a.encrypt(j.concat(b,[i]));for(g=1;g<c;g++){f=a.encrypt(f);for(h=0;h<f.length;h++)e[h]^=f[h]}k=k.concat(e)}if(d)k=j.clamp(k,d);return k};
- sjcl.random={randomWords:function(a,b){var c=[];b=this.isReady(b);var d;if(b===0)throw new sjcl.exception.notReady("generator isn't seeded");else b&2&&this.U(!(b&1));for(b=0;b<a;b+=4){(b+1)%0x10000===0&&this.L();d=this.u();c.push(d[0],d[1],d[2],d[3])}this.L();return c.slice(0,a)},setDefaultParanoia:function(a){this.t=a},addEntropy:function(a,b,c){c=c||"user";var d,e,f=(new Date).valueOf(),g=this.q[c],h=this.isReady();d=this.F[c];if(d===undefined)d=this.F[c]=this.R++;if(g===undefined)g=this.q[c]=0;this.q[c]=
- (this.q[c]+1)%this.b.length;switch(typeof a){case "number":break;case "object":if(b===undefined)for(c=b=0;c<a.length;c++)for(e=a[c];e>0;){b++;e>>>=1}this.b[g].update([d,this.J++,2,b,f,a.length].concat(a));break;case "string":if(b===undefined)b=a.length;this.b[g].update([d,this.J++,3,b,f,a.length]);this.b[g].update(a);break;default:throw new sjcl.exception.bug("random: addEntropy only supports number, array or string");}this.j[g]+=b;this.f+=b;if(h===0){this.isReady()!==0&&this.K("seeded",Math.max(this.g,
- this.f));this.K("progress",this.getProgress())}},isReady:function(a){a=this.B[a!==undefined?a:this.t];return this.g&&this.g>=a?this.j[0]>80&&(new Date).valueOf()>this.O?3:1:this.f>=a?2:0},getProgress:function(a){a=this.B[a?a:this.t];return this.g>=a?1["0"]:this.f>a?1["0"]:this.f/a},startCollectors:function(){if(!this.m){if(window.addEventListener){window.addEventListener("load",this.o,false);window.addEventListener("mousemove",this.p,false)}else if(document.attachEvent){document.attachEvent("onload",
- this.o);document.attachEvent("onmousemove",this.p)}else throw new sjcl.exception.bug("can't attach event");this.m=true}},stopCollectors:function(){if(this.m){if(window.removeEventListener){window.removeEventListener("load",this.o);window.removeEventListener("mousemove",this.p)}else if(window.detachEvent){window.detachEvent("onload",this.o);window.detachEvent("onmousemove",this.p)}this.m=false}},addEventListener:function(a,b){this.r[a][this.Q++]=b},removeEventListener:function(a,b){var c;a=this.r[a];
- var d=[];for(c in a)a.hasOwnProperty(c)&&a[c]===b&&d.push(c);for(b=0;b<d.length;b++){c=d[b];delete a[c]}},b:[new sjcl.hash.sha256],j:[0],z:0,q:{},J:0,F:{},R:0,g:0,f:0,O:0,a:[0,0,0,0,0,0,0,0],d:[0,0,0,0],s:undefined,t:6,m:false,r:{progress:{},seeded:{}},Q:0,B:[0,48,64,96,128,192,0x100,384,512,768,1024],u:function(){for(var a=0;a<4;a++){this.d[a]=this.d[a]+1|0;if(this.d[a])break}return this.s.encrypt(this.d)},L:function(){this.a=this.u().concat(this.u());this.s=new sjcl.cipher.aes(this.a)},T:function(a){this.a=
- sjcl.hash.sha256.hash(this.a.concat(a));this.s=new sjcl.cipher.aes(this.a);for(a=0;a<4;a++){this.d[a]=this.d[a]+1|0;if(this.d[a])break}},U:function(a){var b=[],c=0,d;this.O=b[0]=(new Date).valueOf()+3E4;for(d=0;d<16;d++)b.push(Math.random()*0x100000000|0);for(d=0;d<this.b.length;d++){b=b.concat(this.b[d].finalize());c+=this.j[d];this.j[d]=0;if(!a&&this.z&1<<d)break}if(this.z>=1<<this.b.length){this.b.push(new sjcl.hash.sha256);this.j.push(0)}this.f-=c;if(c>this.g)this.g=c;this.z++;this.T(b)},p:function(a){sjcl.random.addEntropy([a.x||
- a.clientX||a.offsetX,a.y||a.clientY||a.offsetY],2,"mouse")},o:function(){sjcl.random.addEntropy(new Date,2,"loadtime")},K:function(a,b){var c;a=sjcl.random.r[a];var d=[];for(c in a)a.hasOwnProperty(c)&&d.push(a[c]);for(c=0;c<d.length;c++)d[c](b)}};
- sjcl.json={defaults:{v:1,iter:1E3,ks:128,ts:64,mode:"ccm",adata:"",cipher:"aes"},encrypt:function(a,b,c,d){c=c||{};d=d||{};var e=sjcl.json,f=e.c({iv:sjcl.random.randomWords(4,0)},e.defaults);e.c(f,c);if(typeof f.salt==="string")f.salt=sjcl.codec.base64.toBits(f.salt);if(typeof f.iv==="string")f.iv=sjcl.codec.base64.toBits(f.iv);if(!sjcl.mode[f.mode]||!sjcl.cipher[f.cipher]||typeof a==="string"&&f.iter<=100||f.ts!==64&&f.ts!==96&&f.ts!==128||f.ks!==128&&f.ks!==192&&f.ks!==0x100||f.iv.length<2||f.iv.length>
- 4)throw new sjcl.exception.invalid("json encrypt: invalid parameters");if(typeof a==="string"){c=sjcl.misc.cachedPbkdf2(a,f);a=c.key.slice(0,f.ks/32);f.salt=c.salt}if(typeof b==="string")b=sjcl.codec.utf8String.toBits(b);c=new sjcl.cipher[f.cipher](a);e.c(d,f);d.key=a;f.ct=sjcl.mode[f.mode].encrypt(c,b,f.iv,f.adata,f.tag);return e.encode(e.V(f,e.defaults))},decrypt:function(a,b,c,d){c=c||{};d=d||{};var e=sjcl.json;b=e.c(e.c(e.c({},e.defaults),e.decode(b)),c,true);if(typeof b.salt==="string")b.salt=
- sjcl.codec.base64.toBits(b.salt);if(typeof b.iv==="string")b.iv=sjcl.codec.base64.toBits(b.iv);if(!sjcl.mode[b.mode]||!sjcl.cipher[b.cipher]||typeof a==="string"&&b.iter<=100||b.ts!==64&&b.ts!==96&&b.ts!==128||b.ks!==128&&b.ks!==192&&b.ks!==0x100||!b.iv||b.iv.length<2||b.iv.length>4)throw new sjcl.exception.invalid("json decrypt: invalid parameters");if(typeof a==="string"){c=sjcl.misc.cachedPbkdf2(a,b);a=c.key.slice(0,b.ks/32);b.salt=c.salt}c=new sjcl.cipher[b.cipher](a);c=sjcl.mode[b.mode].decrypt(c,
- b.ct,b.iv,b.adata,b.tag);e.c(d,b);d.key=a;return sjcl.codec.utf8String.fromBits(c)},encode:function(a){var b,c="{",d="";for(b in a)if(a.hasOwnProperty(b)){if(!b.match(/^[a-z0-9]+$/i))throw new sjcl.exception.invalid("json encode: invalid property name");c+=d+b+":";d=",";switch(typeof a[b]){case "number":case "boolean":c+=a[b];break;case "string":c+='"'+escape(a[b])+'"';break;case "object":c+='"'+sjcl.codec.base64.fromBits(a[b],1)+'"';break;default:throw new sjcl.exception.bug("json encode: unsupported type");
- }}return c+"}"},decode:function(a){a=a.replace(/\s/g,"");if(!a.match(/^\{.*\}$/))throw new sjcl.exception.invalid("json decode: this isn't json!");a=a.replace(/^\{|\}$/g,"").split(/,/);var b={},c,d;for(c=0;c<a.length;c++){if(!(d=a[c].match(/^([a-z][a-z0-9]*):(?:(\d+)|"([a-z0-9+\/%*_.@=\-]*)")$/i)))throw new sjcl.exception.invalid("json decode: this isn't json!");b[d[1]]=d[2]?parseInt(d[2],10):d[1].match(/^(ct|salt|iv)$/)?sjcl.codec.base64.toBits(d[3]):unescape(d[3])}return b},c:function(a,b,c){if(a===
- undefined)a={};if(b===undefined)return a;var d;for(d in b)if(b.hasOwnProperty(d)){if(c&&a[d]!==undefined&&a[d]!==b[d])throw new sjcl.exception.invalid("required parameter overridden");a[d]=b[d]}return a},V:function(a,b){var c={},d;for(d in a)if(a.hasOwnProperty(d)&&a[d]!==b[d])c[d]=a[d];return c},W:function(a,b){var c={},d;for(d=0;d<b.length;d++)if(a[b[d]]!==undefined)c[b[d]]=a[b[d]];return c}};sjcl.encrypt=sjcl.json.encrypt;sjcl.decrypt=sjcl.json.decrypt;sjcl.misc.S={};
- sjcl.misc.cachedPbkdf2=function(a,b){var c=sjcl.misc.S,d;b=b||{};d=b.iter||1E3;c=c[a]=c[a]||{};d=c[d]=c[d]||{firstSalt:b.salt&&b.salt.length?b.salt.slice(0):sjcl.random.randomWords(2,0)};c=b.salt===undefined?d.firstSalt:b.salt;d[c]=d[c]||sjcl.misc.pbkdf2(a,c,b.iter);return{key:d[c].slice(0),salt:c.slice(0)}};/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CClientScript manages JavaScript and CSS stylesheets for views.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CClientScript.php 3142 2011-03-29 13:27:50Z qiang.xue $
- * @package system.web
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CApplicationComponent
- */
- Yii.CClientScript = function CClientScript () {
- };
- Yii.CClientScript.prototype = new Yii.CApplicationComponent();
- Yii.CClientScript.prototype.constructor = Yii.CClientScript;
- /**
- * @const
- */
- Yii.CClientScript.prototype.POS_HEAD = 0;
- /**
- * @const
- */
- Yii.CClientScript.prototype.POS_BEGIN = 1;
- /**
- * @const
- */
- Yii.CClientScript.prototype.POS_END = 2;
- /**
- * @const
- */
- Yii.CClientScript.prototype.POS_LOAD = 3;
- /**
- * @const
- */
- Yii.CClientScript.prototype.POS_READY = 4;
- /**
- * @var {Boolean} whether JavaScript should be enabled. Defaults to true.
- */
- Yii.CClientScript.prototype.enableJavaScript = true;
- /**
- * @var {Array} the mapping between script file names and the corresponding script URLs.
- * The array keys are script file names (without directory part) and the array values are the corresponding URLs.
- * If an array value is false, the corresponding script file will not be rendered.
- * If an array key is '*.js' or '*.css', the corresponding URL will replace all
- * all JavaScript files or CSS files, respectively.
- *
- * This property is mainly used to optimize the generated HTML pages
- * by merging different scripts files into fewer and optimized script files.
- * @since 1.0.3
- */
- Yii.CClientScript.prototype.scriptMap = [];
- /**
- * @var {Array} list of custom script packages (name=>package spec).
- * This property keeps a list of named script packages, each of which can contain
- * a set of CSS and/or JavaScript script files, and their dependent package names.
- * By calling {@link registerPackage}, one can register a whole package of client
- * scripts together with their dependent packages and render them in the HTML output.
- *
- * The array structure is as follows:
- * <pre>
- * {
- * 'package-name':{
- * 'basePath':'alias of the directory containing the script files',
- * 'baseUrl':'base URL for the script files',
- * 'js':{ of js files relative to basePath/baseUrl = [0];
- * ,
- * 'css':{ of css files relative to basePath/baseUrl = [0];
- * ,
- * 'depends':{ of dependent packages = [0];
- * ,
- * ),
- * ++++++
- * }
- * </pre>
- *
- * The JS and CSS files listed are relative to 'basePath'.
- * For example, if 'basePath' is 'application.assets', a script named 'comments.js'
- * will refer to the file 'protected/assets/comments.js'.
- *
- * When a script is being rendered in HTML, it will be prefixed with 'baseUrl'.
- * For example, if 'baseUrl' is '/assets', the 'comments.js' script will be rendered
- * using URL '/assets/comments.js'.
- *
- * If 'baseUrl' does not start with '/', the relative URL of the application entry
- * script will be inserted at the beginning. For example, if 'baseUrl' is 'assets'
- * and the current application runs with the URL 'http://localhost/demo/index.php',
- * then the 'comments.js' script will be rendered using URL '/demo/assets/comments.js'.
- *
- * If 'baseUrl' is not set, the script will be published by {@link CAssetManager}
- * and the corresponding published URL will be used.
- *
- * When calling {@link registerPackage} to register a script package,
- * this property will be checked first followed by {@link corePackages}.
- * If a package is found, it will be registered for rendering later on.
- *
- * @since 1.1.7
- */
- Yii.CClientScript.prototype.packages = [];
- /**
- * @var {Array} list of core script packages (name=>package spec).
- * Please refer to {@link packages} for details about package spec.
- *
- * By default, the core script packages are specified in 'framework/web/js/packages.php'.
- * You may configure this property to customize the core script packages.
- *
- * When calling {@link registerPackage} to register a script package,
- * {@link packages} will be checked first followed by this property.
- * If a package is found, it will be registered for rendering later on.
- *
- * @since 1.1.7
- */
- Yii.CClientScript.prototype.corePackages = null;
- /**
- * @var {Array} the registered CSS files (CSS URL=>media type).
- * @since 1.0.4
- */
- Yii.CClientScript.prototype.cssFiles = [];
- /**
- * @var {Array} the registered JavaScript files (position, key => URL)
- * @since 1.0.4
- */
- Yii.CClientScript.prototype.scriptFiles = [];
- /**
- * @var {Array} the registered JavaScript code blocks (position, key => code)
- * @since 1.0.5
- */
- Yii.CClientScript.prototype.scripts = [];
- /**
- * @var {Array} the registered head meta tags. Each array element represents an option array
- * that will be passed as the last parameter of {@link CHtml::metaTag}.
- * @since 1.1.3
- */
- Yii.CClientScript.prototype.metaTags = [];
- /**
- * @var {Array} the registered head link tags. Each array element represents an option array
- * that will be passed as the last parameter of {@link CHtml::linkTag}.
- * @since 1.1.3
- */
- Yii.CClientScript.prototype.linkTags = [];
- /**
- * @var {Array} the registered css code blocks (key => array(CSS code, media type)).
- * @since 1.1.3
- */
- Yii.CClientScript.prototype.css = [];
- /**
- * @var {Boolean} whether there are any javascript or css to be rendered.
- * @since 1.1.7
- */
- Yii.CClientScript.prototype.hasScripts = false;
- /**
- * @var {Array} the registered script packages (name => package spec)
- * @since 1.1.7
- */
- Yii.CClientScript.prototype.coreScripts = [];
- /**
- * @var {Integer} Where the scripts registered using {@link registerCoreScript} or {@link registerPackage}
- * will be inserted in the page. This can be one of the CClientScript::POS_* constants.
- * Defaults to CClientScript::POS_HEAD.
- * @since 1.1.3
- */
- Yii.CClientScript.prototype.coreScriptPosition = 0;
- Yii.CClientScript.prototype._baseUrl = null;
- /**
- * Cleans all registered scripts.
- */
- Yii.CClientScript.prototype.reset = function () {
- this.hasScripts=false;
- this.coreScripts=[];
- this.cssFiles=[];
- this.css=[];
- this.scriptFiles=[];
- this.scripts=[];
- this.metaTags=[];
- this.linkTags=[];
- this.recordCachingAction('clientScript','reset',[]);
- };
- /**
- * Renders the registered scripts.
- * This method is called in {@link CController::render} when it finishes
- * rendering content. CClientScript thus gets a chance to insert script tags
- * at <code>head</code> and <code>body</code> sections in the HTML output.
- * @param {String} output the existing output that needs to be inserted with script tags
- */
- Yii.CClientScript.prototype.render = function (output) {
- if(!this.hasScripts) {
- return;
- }
- this.renderCoreScripts();
- if(!php.empty(this.scriptMap)) {
- this.remapScripts();
- }
- this.unifyScripts();
- this.renderHead(output);
- if(this.enableJavaScript) {
- this.renderBodyBegin(output);
- this.renderBodyEnd(output);
- }
- };
- /**
- * Removes duplicated scripts from {@link scriptFiles}.
- * @since 1.1.5
- */
- Yii.CClientScript.prototype.unifyScripts = function () {
- var map, scriptFile, key;
- if(!this.enableJavaScript) {
- return;
- }
- map=[];
- if(this.scriptFiles[this.POS_HEAD] !== undefined) {
- map=this.scriptFiles[this.POS_HEAD];
- }
- if(this.scriptFiles[this.POS_BEGIN] !== undefined) {
- for (key in this.scriptFiles[this.POS_BEGIN]) {
- if (this.scriptFiles[this.POS_BEGIN].hasOwnProperty(key)) {
- scriptFile = this.scriptFiles[this.POS_BEGIN][key];
- if(map[scriptFile] !== undefined) {
- delete this.scriptFiles[this.POS_BEGIN][key];
- }
- else {
- map[scriptFile]=true;
- }
- }
- }
- }
- if(this.scriptFiles[this.POS_END] !== undefined) {
- for (key in this.scriptFiles[this.POS_END]) {
- if (this.scriptFiles[this.POS_END].hasOwnProperty(key)) {
- scriptFile = this.scriptFiles[this.POS_END][key];
- if(map[scriptFile] !== undefined) {
- delete this.scriptFiles[this.POS_END][key];
- }
- }
- }
- }
- };
- /**
- * Uses {@link scriptMap} to re-map the registered scripts.
- * @since 1.0.3
- */
- Yii.CClientScript.prototype.remapScripts = function () {
- var cssFiles, name, url, media, jsFiles, position, scripts, script, key;
- cssFiles=[];
- for (url in this.cssFiles) {
- if (this.cssFiles.hasOwnProperty(url)) {
- media = this.cssFiles[url];
- name=php.basename(url);
- if(this.scriptMap[name] !== undefined) {
- if(this.scriptMap[name]!==false) {
- cssFiles[this.scriptMap[name]]=media;
- }
- }
- else if(this.scriptMap['*.css'] !== undefined) {
- if(this.scriptMap['*.css']!==false) {
- cssFiles[this.scriptMap['*.css']]=media;
- }
- }
- else {
- cssFiles[url]=media;
- }
- }
- }
- this.cssFiles=cssFiles;
- jsFiles=[];
- for (position in this.scriptFiles) {
- if (this.scriptFiles.hasOwnProperty(position)) {
- scripts = this.scriptFiles[position];
- jsFiles[position]=[];
- for (key in scripts) {
- if (scripts.hasOwnProperty(key)) {
- script = scripts[key];
- name=php.basename(script);
- if(this.scriptMap[name] !== undefined) {
- if(this.scriptMap[name]!==false) {
- jsFiles[position][this.scriptMap[name]]=this.scriptMap[name];
- }
- }
- else if(this.scriptMap['*.js'] !== undefined)
- {
- if(this.scriptMap['*.js']!==false) {
- jsFiles[position][this.scriptMap['*.js']]=this.scriptMap['*.js'];
- }
- }
- else {
- jsFiles[position][key]=script;
- }
- }
- }
- }
- }
- this.scriptFiles=jsFiles;
- };
- /**
- * Renders the specified core javascript library.
- * @since 1.0.3
- */
- Yii.CClientScript.prototype.renderCoreScripts = function () {
- var cssFiles, jsFiles, baseUrl, name, packageVar, i, js, n, css, cssFile, media, j, url;
- if(this.coreScripts===null) {
- return;
- }
- cssFiles=[];
- jsFiles=[];
- for (name in this.coreScripts) {
- if (this.coreScripts.hasOwnProperty(name)) {
- packageVar = this.coreScripts[name];
- baseUrl=this.getPackageBaseUrl(name);
- if(!php.empty(packageVar['js']))
- {
- for (i in packageVar['js']) {
- if (packageVar['js'].hasOwnProperty(i)) {
- js = packageVar['js'][i];
- jsFiles[baseUrl+'/'+js]=baseUrl+'/'+js;
- }
- }
- }
- if(!php.empty(packageVar['css']))
- {
- for (n in packageVar['css']) {
- if (packageVar['css'].hasOwnProperty(n)) {
- css = packageVar['css'][n];
- cssFiles[baseUrl+'/'+css]='';
- }
- }
- }
- }
- }
- // merge in place
- if(cssFiles!==[])
- {
- for (cssFile in this.cssFiles) {
- if (this.cssFiles.hasOwnProperty(cssFile)) {
- media = this.cssFiles[cssFile];
- cssFiles[cssFile]=media;
- }
- }
- this.cssFiles=cssFiles;
- }
- if(jsFiles!==[])
- {
- if(this.scriptFiles[this.coreScriptPosition] !== undefined)
- {
- for (j in this.scriptFiles[this.coreScriptPosition]) {
- if (this.scriptFiles[this.coreScriptPosition].hasOwnProperty(j)) {
- url = this.scriptFiles[this.coreScriptPosition][j];
- jsFiles[url]=url;
- }
- }
- }
- this.scriptFiles[this.coreScriptPosition]=jsFiles;
- }
- };
- /**
- * Inserts the scripts in the head section.
- * @param {String} output the output to be inserted with scripts.
- */
- Yii.CClientScript.prototype.renderHead = function (output) {
- var html, i, meta, n, link, url, media, j, css, k, scriptFile, count;
- html='';
- for (i in this.metaTags) {
- if (this.metaTags.hasOwnProperty(i)) {
- meta = this.metaTags[i];
- html+=Yii.CHtml.metaTag(meta['content'],null,null,meta)+"\n";
- }
- }
- for (n in this.linkTags) {
- if (this.linkTags.hasOwnProperty(n)) {
- link = this.linkTags[n];
- html+=Yii.CHtml.linkTag(null,null,null,null,link)+"\n";
- }
- }
- for (url in this.cssFiles) {
- if (this.cssFiles.hasOwnProperty(url)) {
- media = this.cssFiles[url];
- html+=Yii.CHtml.cssFile(url,media)+"\n";
- }
- }
- for (j in this.css) {
- if (this.css.hasOwnProperty(j)) {
- css = this.css[j];
- html+=Yii.CHtml.css(css[0],css[1])+"\n";
- }
- }
- if(this.enableJavaScript)
- {
- if(this.scriptFiles[this.POS_HEAD] !== undefined)
- {
- for (k in this.scriptFiles[this.POS_HEAD]) {
- if (this.scriptFiles[this.POS_HEAD].hasOwnProperty(k)) {
- scriptFile = this.scriptFiles[this.POS_HEAD][k];
- html+=Yii.CHtml.scriptFile(scriptFile)+"\n";
- }
- }
- }
- if(this.scripts[this.POS_HEAD] !== undefined) {
- html+=Yii.CHtml.script(this.scripts[this.POS_HEAD].join("\n"))+"\n";
- }
- }
- if(html!=='')
- {
- count=0;
- output=output.replace('/(<title\b[^>]*>|<\\/head\s*>)/is','<###head###>$1');
- if(count) {
- output=php.str_replace('<###head###>',html,output);
- }
- else {
- output=html+output;
- }
- }
- };
- /**
- * Inserts the scripts at the beginning of the body section.
- * @param {String} output the output to be inserted with scripts.
- */
- Yii.CClientScript.prototype.renderBodyBegin = function (output) {
- var html, i, scriptFile, count;
- html='';
- if(this.scriptFiles[this.POS_BEGIN] !== undefined)
- {
- for (i in this.scriptFiles[this.POS_BEGIN]) {
- if (this.scriptFiles[this.POS_BEGIN].hasOwnProperty(i)) {
- scriptFile = this.scriptFiles[this.POS_BEGIN][i];
- html+=Yii.CHtml.scriptFile(scriptFile)+"\n";
- }
- }
- }
- if(this.scripts[this.POS_BEGIN] !== undefined) {
- html+=Yii.CHtml.script(this.scripts[this.POS_BEGIN].join("\n"))+"\n";
- }
- if(html!=='')
- {
- count=0;
- output=output.replace('/(<body\b[^>]*>)/is','$1<###begin###>');
- if(count) {
- output=php.str_replace('<###begin###>',html,output);
- }
- else {
- output=html+output;
- }
- }
- };
- /**
- * Inserts the scripts at the end of the body section.
- * @param {String} output the output to be inserted with scripts.
- */
- Yii.CClientScript.prototype.renderBodyEnd = function (output) {
- var fullPage, html, i, scriptFile, scripts;
- if(this.scriptFiles[this.POS_END] === undefined && this.scripts[this.POS_END] === undefined
- && this.scripts[this.POS_READY] === undefined && this.scripts[this.POS_LOAD] === undefined) {
- return;
- }
- fullPage=0;
- output=output.replace('/(<\\/body\s*>)/is','<###end###>$1');
- html='';
- if(this.scriptFiles[this.POS_END] !== undefined)
- {
- for (i in this.scriptFiles[this.POS_END]) {
- if (this.scriptFiles[this.POS_END].hasOwnProperty(i)) {
- scriptFile = this.scriptFiles[this.POS_END][i];
- html+=Yii.CHtml.scriptFile(scriptFile)+"\n";
- }
- }
- }
- scripts=this.scripts[this.POS_END] !== undefined ? this.scripts[this.POS_END] : [];
- if(this.scripts[this.POS_READY] !== undefined)
- {
- if(fullPage) {
- scripts.push("jQuery(function($) {\n"+this.scripts[this.POS_READY].join("\n")+"\n});");
- }
- else {
- scripts.push(this.scripts[this.POS_READY].join("\n"));
- }
- }
- if(this.scripts[this.POS_LOAD] !== undefined)
- {
- if(fullPage) {
- scripts.push("jQuery(window).load(function() {\n"+this.scripts[this.POS_LOAD].join("\n")+"\n});");
- }
- else {
- scripts.push(this.scripts[this.POS_LOAD].join("\n"));
- }
- }
- if(!php.empty(scripts)) {
- html+=Yii.CHtml.script(scripts.join("\n"))+"\n";
- }
- if(fullPage) {
- output=php.str_replace('<###end###>',html,output);
- }
- else {
- output=output+html;
- }
- };
- /**
- * Returns the base URL of all core javascript files.
- * If the base URL is not explicitly set, this method will publish the whole directory
- * 'framework/web/js/source' and return the corresponding URL.
- * @returns {String} the base URL of all core javascript files
- */
- Yii.CClientScript.prototype.getCoreScriptUrl = function () {
- if(this._baseUrl!==null) {
- return this._baseUrl;
- }
- else {
- return (this._baseUrl=Yii.app().getAssetManager().publish(YII_PATH+'/web/js/source'));
- }
- };
- /**
- * Sets the base URL of all core javascript files.
- * This setter is provided in case when core javascript files are manually published
- * to a pre-specified location. This may save asset publishing time for large-scale applications.
- * @param {String} value the base URL of all core javascript files.
- */
- Yii.CClientScript.prototype.setCoreScriptUrl = function (value) {
- this._baseUrl=value;
- };
- /**
- * Returns the base URL for a registered package with the specified name.
- * If needed, this method may publish the assets of the package and returns the published base URL.
- * @param {String} name the package name
- * @returns {String} the base URL for the named package. False is returned if the package is not registered yet.
- * @see registerPackage
- * @since 1.1.8
- */
- Yii.CClientScript.prototype.getPackageBaseUrl = function (name) {
- var packageVar, baseUrl;
- if(this.coreScripts[name] === undefined) {
- return false;
- }
- packageVar=this.coreScripts[name];
- if(packageVar['baseUrl'] !== undefined)
- {
- baseUrl=packageVar['baseUrl'];
- if(baseUrl==='' || baseUrl[0]!=='/' && php.strpos(baseUrl,'://')===false) {
- baseUrl=Yii.app().getRequest().getBaseUrl()+'/'+baseUrl;
- }
- baseUrl=php.rtrim(baseUrl,'/');
- }
- else if(packageVar['basePath'] !== undefined) {
- baseUrl=Yii.app().getAssetManager().publish(Yii.getPathOfAlias(packageVar['basePath']));
- }
- else {
- baseUrl=this.getCoreScriptUrl();
- }
- return (this.coreScripts[name]['baseUrl']=baseUrl);
- };
- /**
- * Registers a script package that is listed in {@link packages}.
- * This method is the same as {@link registerCoreScript}.
- * @param {String} name the name of the script package.
- * @returns {Yii.CClientScript} the CClientScript object itself (to support method chaining, available since version 1.1.5).
- * @since 1.1.7
- * @see renderCoreScript
- */
- Yii.CClientScript.prototype.registerPackage = function (name) {
- return this.registerCoreScript(name);
- };
- /**
- * Registers a script package that is listed in {@link packages}.
- * @param {String} name the name of the script package.
- * @returns {Yii.CClientScript} the CClientScript object itself (to support method chaining, available since version 1.1.5).
- * @see renderCoreScript
- */
- Yii.CClientScript.prototype.registerCoreScript = function (name) {
- var packageVar, i, p, params;
- if(this.coreScripts[name] !== undefined) {
- return this;
- }
- if(this.packages[name] !== undefined) {
- packageVar=this.packages[name];
- }
- else
- {
- if(this.corePackages===null) {
- this.corePackages=require(YII_PATH+'/web/js/packages.php');
- }
- if(this.corePackages[name] !== undefined) {
- packageVar=this.corePackages[name];
- }
- }
- if(packageVar !== undefined)
- {
- if(!php.empty(packageVar['depends']))
- {
- for (i in packageVar['depends']) {
- if (packageVar['depends'].hasOwnProperty(i)) {
- p = packageVar['depends'][i];
- this.registerCoreScript(p);
- }
- }
- }
- this.coreScripts[name]=packageVar;
- this.hasScripts=true;
- params=func_get_args();
- this.recordCachingAction('clientScript','registerCoreScript',params);
- }
- return this;
- };
- /**
- * Registers a CSS file
- * @param {String} url URL of the CSS file
- * @param {String} media media that the CSS file should be applied to. If empty, it means all media types.
- * @returns {Yii.CClientScript} the CClientScript object itself (to support method chaining, available since version 1.1.5).
- */
- Yii.CClientScript.prototype.registerCssFile = function (url, media) {
- var params;
- if (media === undefined) {
- media = '';
- }
- this.hasScripts=true;
- this.cssFiles[url]=media;
- params=func_get_args();
- this.recordCachingAction('clientScript','registerCssFile',params);
- return this;
- };
- /**
- * Registers a piece of CSS code.
- * @param {String} id ID that uniquely identifies this piece of CSS code
- * @param {String} css the CSS code
- * @param {String} media media that the CSS code should be applied to. If empty, it means all media types.
- * @returns {Yii.CClientScript} the CClientScript object itself (to support method chaining, available since version 1.1.5).
- */
- Yii.CClientScript.prototype.registerCss = function (id, css, media) {
- var params;
- if (media === undefined) {
- media = '';
- }
- this.hasScripts=true;
- this.css[id]=[css,media];
- params=func_get_args();
- this.recordCachingAction('clientScript','registerCss',params);
- return this;
- };
- /**
- * Registers a javascript file.
- * @param {String} url URL of the javascript file
- * @param {Integer} position the position of the JavaScript code. Valid values include the following:
- * <ul>
- * <li>CClientScript::POS_HEAD : the script is inserted in the head section right before the title element.</li>
- * <li>CClientScript::POS_BEGIN : the script is inserted at the beginning of the body section.</li>
- * <li>CClientScript::POS_END : the script is inserted at the end of the body section.</li>
- * </ul>
- * @returns {Yii.CClientScript} the CClientScript object itself (to support method chaining, available since version 1.1.5).
- */
- Yii.CClientScript.prototype.registerScriptFile = function (url, position) {
- var params;
- if (position === undefined) {
- position = 0;
- }
- this.hasScripts=true;
- this.scriptFiles[position][url]=url;
- params=func_get_args();
- this.recordCachingAction('clientScript','registerScriptFile',params);
- return this;
- };
- /**
- * Registers a piece of javascript code.
- * @param {String} id ID that uniquely identifies this piece of JavaScript code
- * @param {String} script the javascript code
- * @param {Integer} position the position of the JavaScript code. Valid values include the following:
- * <ul>
- * <li>CClientScript::POS_HEAD : the script is inserted in the head section right before the title element.</li>
- * <li>CClientScript::POS_BEGIN : the script is inserted at the beginning of the body section.</li>
- * <li>CClientScript::POS_END : the script is inserted at the end of the body section.</li>
- * <li>CClientScript::POS_LOAD : the script is inserted in the window.onload() function.</li>
- * <li>CClientScript::POS_READY : the script is inserted in the jQuery's ready function.</li>
- * </ul>
- * @returns {Yii.CClientScript} the CClientScript object itself (to support method chaining, available since version 1.1.5).
- */
- Yii.CClientScript.prototype.registerScript = function (id, script, position) {
- var params;
- if (position === undefined) {
- position = 4;
- }
- this.hasScripts=true;
- this.scripts[position][id]=script;
- if(position===this.POS_READY || position===this.POS_LOAD) {
- this.registerCoreScript('jquery');
- }
- params=func_get_args();
- this.recordCachingAction('clientScript','registerScript',params);
- return this;
- };
- /**
- * Registers a meta tag that will be inserted in the head section (right before the title element) of the resulting page.
- * @param {String} content content attribute of the meta tag
- * @param {String} name name attribute of the meta tag. If null, the attribute will not be generated
- * @param {String} httpEquiv http-equiv attribute of the meta tag. If null, the attribute will not be generated
- * @param {Array} options other options in name-value pairs (e.g. 'scheme', 'lang')
- * @returns {Yii.CClientScript} the CClientScript object itself (to support method chaining, available since version 1.1.5).
- * @since 1.0.1
- */
- Yii.CClientScript.prototype.registerMetaTag = function (content, name, httpEquiv, options) {
- var params;
- if (name === undefined) {
- name = null;
- }
- if (httpEquiv === undefined) {
- httpEquiv = null;
- }
- if (options === undefined) {
- options = [];
- }
- this.hasScripts=true;
- if(name!==null) {
- options['name']=name;
- }
- if(httpEquiv!==null) {
- options['http-equiv']=httpEquiv;
- }
- options['content']=content;
- this.metaTags[serialize(options)]=options;
- params=func_get_args();
- this.recordCachingAction('clientScript','registerMetaTag',params);
- return this;
- };
- /**
- * Registers a link tag that will be inserted in the head section (right before the title element) of the resulting page.
- * @param {String} relation rel attribute of the link tag. If null, the attribute will not be generated.
- * @param {String} type type attribute of the link tag. If null, the attribute will not be generated.
- * @param {String} href href attribute of the link tag. If null, the attribute will not be generated.
- * @param {String} media media attribute of the link tag. If null, the attribute will not be generated.
- * @param {Array} options other options in name-value pairs
- * @returns {Yii.CClientScript} the CClientScript object itself (to support method chaining, available since version 1.1.5).
- * @since 1.0.1
- */
- Yii.CClientScript.prototype.registerLinkTag = function (relation, type, href, media, options) {
- var params;
- if (relation === undefined) {
- relation = null;
- }
- if (type === undefined) {
- type = null;
- }
- if (href === undefined) {
- href = null;
- }
- if (media === undefined) {
- media = null;
- }
- if (options === undefined) {
- options = [];
- }
- this.hasScripts=true;
- if(relation!==null) {
- options['rel']=relation;
- }
- if(type!==null) {
- options['type']=type;
- }
- if(href!==null) {
- options['href']=href;
- }
- if(media!==null) {
- options['media']=media;
- }
- this.linkTags[serialize(options)]=options;
- params=func_get_args();
- this.recordCachingAction('clientScript','registerLinkTag',params);
- return this;
- };
- /**
- * Checks whether the CSS file has been registered.
- * @param {String} url URL of the CSS file
- * @returns {Boolean} whether the CSS file is already registered
- */
- Yii.CClientScript.prototype.isCssFileRegistered = function (url) {
- return this.cssFiles[url] !== undefined;
- };
- /**
- * Checks whether the CSS code has been registered.
- * @param {String} id ID that uniquely identifies the CSS code
- * @returns {Boolean} whether the CSS code is already registered
- */
- Yii.CClientScript.prototype.isCssRegistered = function (id) {
- return this.css[id] !== undefined;
- };
- /**
- * Checks whether the JavaScript file has been registered.
- * @param {String} url URL of the javascript file
- * @param {Integer} position the position of the JavaScript code. Valid values include the following:
- * <ul>
- * <li>CClientScript::POS_HEAD : the script is inserted in the head section right before the title element.</li>
- * <li>CClientScript::POS_BEGIN : the script is inserted at the beginning of the body section.</li>
- * <li>CClientScript::POS_END : the script is inserted at the end of the body section.</li>
- * </ul>
- * @returns {Boolean} whether the javascript file is already registered
- */
- Yii.CClientScript.prototype.isScriptFileRegistered = function (url, position) {
- if (position === undefined) {
- position = 0;
- }
- return this.scriptFiles[position][url] !== undefined;
- };
- /**
- * Checks whether the JavaScript code has been registered.
- * @param {String} id ID that uniquely identifies the JavaScript code
- * @param {Integer} position the position of the JavaScript code. Valid values include the following:
- * <ul>
- * <li>CClientScript::POS_HEAD : the script is inserted in the head section right before the title element.</li>
- * <li>CClientScript::POS_BEGIN : the script is inserted at the beginning of the body section.</li>
- * <li>CClientScript::POS_END : the script is inserted at the end of the body section.</li>
- * <li>CClientScript::POS_LOAD : the script is inserted in the window.onload() function.</li>
- * <li>CClientScript::POS_READY : the script is inserted in the jQuery's ready function.</li>
- * </ul>
- * @returns {Boolean} whether the javascript code is already registered
- */
- Yii.CClientScript.prototype.isScriptRegistered = function (id, position) {
- if (position === undefined) {
- position = 4;
- }
- return this.scripts[position][id] !== undefined;
- };
- /**
- * Records a method call when an output cache is in effect.
- * This is a shortcut to Yii::app()->controller->recordCachingAction.
- * In case when controller is absent, nothing is recorded.
- * @param {String} context a property name of the controller. It refers to an object
- * whose method is being called. If empty it means the controller itself.
- * @param {String} method the method name
- * @param {Array} params parameters passed to the method
- * @see COutputCache
- * @since 1.0.5
- */
- Yii.CClientScript.prototype.recordCachingAction = function (context, method, params) {
- var controller;
- if((controller=Yii.app().getController())!==null) {
- controller.recordCachingAction(context,method,params);
- }
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CController manages a set of actions which deal with the corresponding user requests.
- *
- * Through the actions, CController coordinates the data flow between models and views.
- *
- * When a user requests an action 'XYZ', CController will do one of the following:
- * 1. Method-based action: call method 'actionXYZ' if it exists;
- * 2. Class-based action: create an instance of class 'XYZ' if the class is found in the action class map
- * (specified via {@link actions()}, and execute the action;
- * 3. Call {@link missingAction()}, which by default will raise a 404 HTTP exception.
- *
- * If the user does not specify an action, CController will run the action specified by
- * {@link defaultAction}, instead.
- *
- * CController may be configured to execute filters before and after running actions.
- * Filters preprocess/postprocess the user request/response and may quit executing actions
- * if needed. They are executed in the order they are specified. If during the execution,
- * any of the filters returns true, the rest filters and the action will no longer get executed.
- *
- * Filters can be individual objects, or methods defined in the controller class.
- * They are specified by overriding {@link filters()} method. The following is an example
- * of the filter specification:
- * <pre>
- * {
- * 'accessControl - login',
- * 'ajaxOnly + search',
- * {
- * 'COutputCache + list',
- * 'duration':300,
- * },
- * }
- * </pre>
- * The above example declares three filters: accessControl, ajaxOnly, COutputCache. The first two
- * are method-based filters (defined in CController), which refer to filtering methods in the controller class;
- * while the last refers to a object-based filter whose class is 'system.web.widgets.COutputCache' and
- * the 'duration' property is initialized as 300 (s).
- *
- * For method-based filters, a method named 'filterXYZ($filterChain)' in the controller class
- * will be executed, where 'XYZ' stands for the filter name as specified in {@link filters()}.
- * Note, inside the filter method, you must call <code>$filterChain->run()</code> if the action should
- * be executed. Otherwise, the filtering process would stop at this filter.
- *
- * Filters can be specified so that they are executed only when running certain actions.
- * For method-based filters, this is done by using '+' and '-' operators in the filter specification.
- * The '+' operator means the filter runs only when the specified actions are requested;
- * while the '-' operator means the filter runs only when the requested action is not among those actions.
- * For object-based filters, the '+' and '-' operators are following the class name.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CController.php 3137 2011-03-28 11:08:06Z mdomba $
- * @package system.web
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CBaseController
- */
- Yii.CController = function CController(id, module) {
- if (id !== false) {
- this.construct(id, module);
- }
- };
- Yii.CController.prototype = new Yii.CBaseController();
- Yii.CController.prototype.constructor = Yii.CController;
- /**
- * @const
- */
- Yii.CController.prototype.STATE_INPUT_NAME = 'YII_PAGE_STATE';
- /**
- * @var {Mixed} the name of the layout to be applied to this controller's views.
- * Defaults to null, meaning the {@link CWebApplication::layout application layout}
- * is used. If it is false, no layout will be applied.
- * Since version 1.0.3, the {@link CWebModule::layout module layout} will be used
- * if the controller belongs to a module and this layout property is null.
- */
- Yii.CController.prototype.layout = null;
- /**
- * @var {String} the name of the default action. Defaults to 'index'.
- */
- Yii.CController.prototype.defaultAction = 'index';
- Yii.CController.prototype._id = null;
- Yii.CController.prototype._action = null;
- Yii.CController.prototype._pageTitle = null;
- Yii.CController.prototype._cachingStack = null;
- Yii.CController.prototype._clips = null;
- Yii.CController.prototype._dynamicOutput = null;
- Yii.CController.prototype._pageStates = null;
- Yii.CController.prototype._module = null;
- /**
- * jQuery events to delegate for this controller.
- * Array should be of the following format:
- * <pre>
- * [
- * ['#selector a.someLink', 'click', function (e) { alert("clicked!")}],
- * ['#selector form', 'submit', function (e) { alert('Submitted!'); e.preventDefault(); }]
- * ]
- * </pre>
- * These events will be bound to their selectors when the controller is run
- * @var Array
- */
- Yii.CController.prototype.delegates = [];
- /**
- * @param {String} id id of this controller
- * @param {Yii.CWebModule} module the module that this controller belongs to. This parameter
- * has been available since version 1.0.3.
- */
- Yii.CController.prototype.construct = function (id, module) {
- if (module === undefined) {
- module = null;
- }
- this._id=id;
- this._module=module;
- this.attachBehaviors(this.behaviors());
- };
- /**
- * Initializes the controller.
- * This method is called by the application before the controller starts to execute.
- * You may override this method to perform the needed initialization for the controller.
- * @since 1.0.1
- */
- Yii.CController.prototype.init = function () {
- Yii.forEach(this.delegates, function(i, item) {
- jQuery("body").undelegate(item[0], item[1]).delegate(item[0], item[1], item[2]);
- });
- };
- /**
- * Returns the filter configurations.
- *
- * By overriding this method, child classes can specify filters to be applied to actions.
- *
- * This method returns an array of filter specifications. Each array element specify a single filter.
- *
- * For a method-based filter (called inline filter), it is specified as 'FilterName[ +|- Action1, Action2, ...]',
- * where the '+' ('-') operators describe which actions should be (should not be) applied with the filter.
- *
- * For a class-based filter, it is specified as an array like the following:
- * <pre>
- * {
- * 'FilterClass[ +|- Action1, Action2, ...]',
- * 'name1':'value1',
- * 'name2':'value2',
- * +++
- * }
- * </pre>
- * where the name-value pairs will be used to initialize the properties of the filter.
- *
- * Note, in order to inherit filters defined in the parent class, a child class needs to
- * merge the parent filters with child filters using functions like array_merge().
- *
- * @returns {Object} a list of filter configurations.
- * @see CFilter
- */
- Yii.CController.prototype.filters = function () {
- return {};
- };
- /**
- * Returns a list of external action classes.
- * Array keys are action IDs, and array values are the corresponding
- * action class in dot syntax (e.g. 'edit'=>'application.controllers.article.EditArticle')
- * or arrays representing the configuration of the actions, such as the following,
- * <pre>
- * return {
- * 'action1':'path.to.Action1Class',
- * 'action2':{
- * 'class':'path.to.Action2Class',
- * 'property1':'value1',
- * 'property2':'value2',
- * },
- * };
- * </pre>
- * Derived classes may override this method to declare external actions.
- *
- * Note, in order to inherit actions defined in the parent class, a child class needs to
- * merge the parent actions with child actions using functions like array_merge().
- *
- * Since version 1.0.1, you may import actions from an action provider
- * (such as a widget, see {@link CWidget::actions}), like the following:
- * <pre>
- * return {
- * +++other actions+++
- * // import actions declared in ProviderClass::actions()
- * // the action IDs will be prefixed with 'pro.'
- * 'pro.':'path.to.ProviderClass',
- * // similar as above except that the imported actions are
- * // configured with the specified initial property values
- * 'pro2.':{
- * 'class':'path.to.ProviderClass',
- * 'action1':{
- * 'property1':'value1',
- * },
- * 'action2':{
- * 'property2':'value2',
- * },
- * ),
- * }
- * </pre>
- *
- * In the above, we differentiate action providers from other action
- * declarations by the array keys. For action providers, the array keys
- * must contain a dot. As a result, an action ID 'pro2.action1' will
- * be resolved as the 'action1' action declared in the 'ProviderClass'.
- *
- * @returns {Object} list of external action classes
- * @see createAction
- */
- Yii.CController.prototype.actions = function () {
- return {};
- };
- /**
- * Returns a list of behaviors that this controller should behave as.
- * The return value should be an array of behavior configurations indexed by
- * behavior names. Each behavior configuration can be either a string specifying
- * the behavior class or an array of the following structure:
- * <pre>
- * 'behaviorName':{
- * 'class':'path.to.BehaviorClass',
- * 'property1':'value1',
- * 'property2':'value2',
- * }
- * </pre>
- *
- * Note, the behavior classes must implement {@link IBehavior} or extend from
- * {@link CBehavior}. Behaviors declared in this method will be attached
- * to the controller when it is instantiated.
- *
- * For more details about behaviors, see {@link CComponent}.
- * @returns {Object} the behavior configurations (behavior name=>behavior configuration)
- * @since 1.0.6
- */
- Yii.CController.prototype.behaviors = function () {
- return {};
- };
- /**
- * Returns the access rules for this controller.
- * Override this method if you use the {@link filterAccessControl accessControl} filter.
- * @returns {Array} list of access rules. See {@link CAccessControlFilter} for details about rule specification.
- */
- Yii.CController.prototype.accessRules = function () {
- return [];
- };
- /**
- * Runs the named action.
- * Filters specified via {@link filters()} will be applied.
- * @param {String} actionID action ID
- * @throws {Yii.CHttpException} if the action does not exist or the action name is not proper.
- * @see filters
- * @see createAction
- * @see runAction
- */
- Yii.CController.prototype.run = function (actionID) {
- var action, parent;
- if((action=this.createAction(actionID))!==null) {
-
- if((parent=this.getModule())===null) {
-
- parent=Yii.app();
- }
- if(parent.beforeControllerAction(this,action)) {
- this.runActionWithFilters(action,this.filters());
- parent.afterControllerAction(this,action);
- }
-
- }
- else {
-
- this.missingAction(actionID);
- }
- };
- /**
- * Runs an action with the specified filters.
- * A filter chain will be created based on the specified filters
- * and the action will be executed then.
- * @param {Yii.CAction} action the action to be executed.
- * @param {Array} filters list of filters to be applied to the action.
- * @see filters
- * @see createAction
- * @see runAction
- */
- Yii.CController.prototype.runActionWithFilters = function (action, filters) {
- var priorAction;
- if(php.empty(filters)) {
- this.runAction(action);
- }
- else
- {
- priorAction=this._action;
- this._action=action;
- Yii.CFilterChain.prototype.create(this,action,filters).run();
- this._action=priorAction;
- }
- };
- /**
- * Runs the action after passing through all filters.
- * This method is invoked by {@link runActionWithFilters} after all possible filters have been executed
- * and the action starts to run.
- * @param {Yii.CAction} action action to run
- */
- Yii.CController.prototype.runAction = function (action) {
-
- this._action=action;
- if(this.beforeAction(action)) {
- if(action.runWithParams(this.getActionParams())===false) {
- this.invalidActionParams(action);
- }
- else {
- this.afterAction(action);
- }
- }
- };
- /**
- * Returns the request parameters that will be used for action parameter binding.
- * By default, this method will return $_GET. You may override this method if you
- * want to use other request parameters (e.g. $_GET+$_POST).
- * @returns {Array} the request parameters to be used for action parameter binding
- * @since 1.1.7
- */
- Yii.CController.prototype.getActionParams = function () {
- return Yii.app().getRequest().params;
- };
- /**
- * This method is invoked when the request parameters do not satisfy the requirement of the specified action.
- * The default implementation will throw a 400 HTTP exception.
- * @param {Yii.CAction} action the action being executed
- * @since 1.1.7
- */
- Yii.CController.prototype.invalidActionParams = function (action) {
- throw new Yii.CHttpException(400,Yii.t('yii','Your request is invalid.'));
- };
- /**
- * Postprocesses the output generated by {@link render()}.
- * This method is invoked at the end of {@link render()} and {@link renderText()}.
- * If there are registered client scripts, this method will insert them into the output
- * at appropriate places. If there are dynamic contents, they will also be inserted.
- * This method may also save the persistent page states in hidden fields of
- * stateful forms in the page.
- * @param {String} output the output generated by the current action
- * @returns {String} the output that has been processed.
- */
- Yii.CController.prototype.processOutput = function (output) {
- Yii.app().getClientScript().render(output);
- // if using page caching, we should delay dynamic output replacement
- if(this._dynamicOutput!==null && this.isCachingStackEmpty())
- {
- output=this.processDynamicOutput(output);
- this._dynamicOutput=null;
- }
- if(this._pageStates===null) {
- this._pageStates=this.loadPageStates();
- }
- if(!php.empty(this._pageStates)) {
- output = this.savePageStates(this._pageStates,output);
- }
- return output;
- };
- /**
- * Postprocesses the dynamic output.
- * This method is internally used. Do not call this method directly.
- * @param {String} output output to be processed
- * @returns {String} the processed output
- * @since 1.0.4
- */
- Yii.CController.prototype.processDynamicOutput = function (output) {
- if(this._dynamicOutput) {
- output=output.replace(/<###dynamic-(\d+)###>/,Yii.getFunction([this,'replaceDynamicOutput']));
- }
- return output;
- };
- /**
- * Replaces the dynamic content placeholders with actual content.
- * This is a callback function used internally.
- * @param {Array} matches matches
- * @returns {String} the replacement
- * @see processOutput
- */
- Yii.CController.prototype.replaceDynamicOutput = function (matches) {
- var content;
- content=matches[0];
- if(this._dynamicOutput[matches[1]] !== undefined) {
- content=this._dynamicOutput[matches[1]];
- this._dynamicOutput[matches[1]]=null;
- }
- return content;
- };
- /**
- * Creates the action instance based on the action name.
- * The action can be either an inline action or an object.
- * The latter is created by looking up the action map specified in {@link actions}.
- * @param {String} actionID ID of the action. If empty, the {@link defaultAction default action} will be used.
- * @returns {Yii.CAction} the action instance, null if the action does not exist.
- * @see actions
- */
- Yii.CController.prototype.createAction = function (actionID) {
- var action;
- if(actionID==='') {
- actionID=this.defaultAction;
- }
- actionID = php.ucfirst(actionID);
-
- if(php.method_exists(this,'action'+actionID) && php.strcasecmp(actionID,'s')) { // we have actions method
-
- return new Yii.CInlineAction(this,actionID);
- }
- else {
-
- action=this.createActionFromMap(this.actions(),actionID,actionID);
-
- if(action!==null && action['run'] === undefined) {
- throw new Yii.CException(Yii.t('yii', 'Action class {class} must implement the "run" method.', {'{class}':php.get_class(action)}));
- }
-
- return action;
- }
- };
- /**
- * Creates the action instance based on the action map.
- * This method will check to see if the action ID appears in the given
- * action map. If so, the corresponding configuration will be used to
- * create the action instance.
- * @param {Array} actionMap the action map
- * @param {String} actionID the action ID that has its prefix stripped off
- * @param {String} requestActionID the originally requested action ID
- * @param {Array} config the action configuration that should be applied on top of the configuration specified in the map
- * @returns {Yii.CAction} the action instance, null if the action does not exist.
- * @since 1.0.1
- */
- Yii.CController.prototype.createActionFromMap = function (actionMap, actionID, requestActionID, config) {
- var pos, baseConfig, prefix, provider, providerType, classVar, map;
- actionID = php.lcfirst(actionID);
-
- requestActionID = php.lcfirst(requestActionID);
- if (config === undefined) {
- config = [];
- }
- if((pos=php.strpos(actionID,'.'))===false && actionMap[actionID] !== undefined) {
- baseConfig= typeof actionMap[actionID] === 'object' ? actionMap[actionID] : {'class':actionMap[actionID]};
- return Yii.createComponent(php.empty(config)?baseConfig:php.array_merge(baseConfig,config),this,requestActionID);
- }
- else if(pos===false) {
- return null;
- }
-
- // the action is defined in a provider
- prefix=actionID.slice(0, pos+1);
- if(actionMap[prefix] === undefined) {
- return null;
- }
- actionID=String(actionID.slice(pos+1));
- provider=actionMap[prefix];
- if(typeof(provider) === 'string') {
- providerType=provider;
- }
- else if(typeof provider === 'object' && provider['class'] !== undefined) {
- providerType=provider['class'];
- if(provider[actionID] !== undefined) {
- if(typeof(provider[actionID]) === 'string') {
- config=php.array_merge({'class':provider[actionID]},config);
- }
- else {
- config=php.array_merge(provider[actionID],config);
- }
- }
- }
- else {
- throw new Yii.CException(Yii.t('yii','Object configuration must be an array containing a "class" element.'));
- }
- classVar=Yii.imports(providerType,true);
- map=php.call_user_func([classVar,'actions']);
- return this.createActionFromMap(map,actionID,requestActionID,config);
- };
- /**
- * Handles the request whose action is not recognized.
- * This method is invoked when the controller cannot find the requested action.
- * The default implementation simply throws an exception.
- * @param {String} actionID the missing action name
- * @throws {Yii.CHttpException} whenever this method is invoked
- */
- Yii.CController.prototype.missingAction = function (actionID) {
- throw new Yii.CHttpException(404,Yii.t('yii','The system is unable to find the requested action "{action}".',
- {'{action}':actionID===''?this.defaultAction:actionID}));
- };
- /**
- * @returns {Yii.CAction} the action currently being executed, null if no active action.
- */
- Yii.CController.prototype.getAction = function () {
- return this._action;
- };
- /**
- * @param {Yii.CAction} value the action currently being executed.
- */
- Yii.CController.prototype.setAction = function (value) {
- this._action=value;
- };
- /**
- * @returns {String} ID of the controller
- */
- Yii.CController.prototype.getId = function () {
- return this._id;
- };
- /**
- * @returns {String} the controller ID that is prefixed with the module ID (if any).
- * @since 1.0.3
- */
- Yii.CController.prototype.getUniqueId = function () {
- return this._module ? this._module.getId()+'/'+this._id : this._id;
- };
- /**
- * @returns {String} the route (module ID, controller ID and action ID) of the current request.
- * @since 1.1.0
- */
- Yii.CController.prototype.getRoute = function () {
- var action;
- if((action=this.getAction())!==null) {
- return this.getUniqueId()+'/'+action.getId();
- }
- else {
- return this.getUniqueId();
- }
- };
- /**
- * @returns {Yii.CWebModule} the module that this controller belongs to. It returns null
- * if the controller does not belong to any module
- * @since 1.0.3
- */
- Yii.CController.prototype.getModule = function () {
- return this._module;
- };
- /**
- * Returns the directory containing view files for this controller.
- * The default implementation returns 'protected/views/ControllerID'.
- * Child classes may override this method to use customized view path.
- * If the controller belongs to a module (since version 1.0.3), the default view path
- * is the {@link CWebModule::getViewPath module view path} appended with the controller ID.
- * @returns {String} the directory containing the view files for this controller. Defaults to 'protected/views/ControllerID'.
- */
- Yii.CController.prototype.getViewPath = function () {
- var module;
- if((module=this.getModule())===null) {
- module=Yii.app();
- }
- return module.getViewPath()+'/'+this.getId();
- };
- /**
- * Looks for the view file according to the given view name.
- *
- * When a theme is currently active, this method will call {@link CTheme::getViewFile} to determine
- * which view file should be returned.
- *
- * Otherwise, this method will return the corresponding view file based on the following criteria:
- * <ul>
- * <li>absolute view within a module: the view name starts with a single slash '/'.
- * In this case, the view will be searched for under the currently active module's view path.
- * If there is no active module, the view will be searched for under the application's view path.</li>
- * <li>absolute view within the application: the view name starts with double slashes '//'.
- * In this case, the view will be searched for under the application's view path.
- * This syntax has been available since version 1.1.3.</li>
- * <li>aliased view: the view name contains dots and refers to a path alias.
- * The view file is determined by calling {@link YiiBase::getPathOfAlias()}. Note that aliased views
- * cannot be themed because they can refer to a view file located at arbitrary places.</li>
- * <li>relative view: otherwise. Relative views will be searched for under the currently active
- * controller's view path.</li>
- * </ul>
- *
- * After the view file is identified, this method may further call {@link CApplication::findLocalizedFile}
- * to find its localized version if internationalization is needed.
- *
- * @param {String} viewName view name
- * @returns {String} the view file path, false if the view file does not exist
- * @see resolveViewFile
- * @see CApplication::findLocalizedFile
- */
- Yii.CController.prototype.getViewFile = function (viewName) {
- var theme, viewFile, moduleViewPath, basePath, module;
- if((theme=Yii.app().getTheme())!==null && (viewFile=theme.getViewFile(this,viewName))!==false) {
- return viewFile;
- }
- moduleViewPath=basePath=Yii.app().getViewPath();
- if((module=this.getModule())!==null) {
- moduleViewPath=module.getViewPath();
- }
- return this.resolveViewFile(viewName,this.getViewPath(),basePath,moduleViewPath);
- };
- /**
- * Looks for the layout view script based on the layout name.
- *
- * The layout name can be specified in one of the following ways:
- *
- * <ul>
- * <li>layout is false: returns false, meaning no layout.</li>
- * <li>layout is null: the currently active module's layout will be used. If there is no active module,
- * the application's layout will be used.</li>
- * <li>a regular view name.</li>
- * </ul>
- *
- * The resolution of the view file based on the layout view is similar to that in {@link getViewFile}.
- * In particular, the following rules are followed:
- *
- * Otherwise, this method will return the corresponding view file based on the following criteria:
- * <ul>
- * <li>When a theme is currently active, this method will call {@link CTheme::getLayoutFile} to determine
- * which view file should be returned.</li>
- * <li>absolute view within a module: the view name starts with a single slash '/'.
- * In this case, the view will be searched for under the currently active module's view path.
- * If there is no active module, the view will be searched for under the application's view path.</li>
- * <li>absolute view within the application: the view name starts with double slashes '//'.
- * In this case, the view will be searched for under the application's view path.
- * This syntax has been available since version 1.1.3.</li>
- * <li>aliased view: the view name contains dots and refers to a path alias.
- * The view file is determined by calling {@link YiiBase::getPathOfAlias()}. Note that aliased views
- * cannot be themed because they can refer to a view file located at arbitrary places.</li>
- * <li>relative view: otherwise. Relative views will be searched for under the currently active
- * module's layout path. In case when there is no active module, the view will be searched for
- * under the application's layout path.</li>
- * </ul>
- *
- * After the view file is identified, this method may further call {@link CApplication::findLocalizedFile}
- * to find its localized version if internationalization is needed.
- *
- * @param {Mixed} layoutName layout name
- * @returns {String} the view file for the layout. False if the view file cannot be found
- */
- Yii.CController.prototype.getLayoutFile = function (layoutName) {
- var theme, layoutFile, module;
- if(layoutName===false) {
- return false;
- }
- if((theme=Yii.app().getTheme())!==null && (layoutFile=theme.getLayoutFile(this,layoutName))!==false) {
- return layoutFile;
- }
- if(php.empty(layoutName)) {
- module=this.getModule();
- while(module!==null) {
- if(module.layout===false) {
- return false;
- }
- if(!php.empty(module.layout)) {
- break;
- }
- module=module.getParentModule();
- }
- if(module===null) {
- module=Yii.app();
- }
- layoutName=module.layout;
- }
- else if((module=this.getModule())===null) {
- module=Yii.app();
- }
- return this.resolveViewFile(layoutName,module.getLayoutPath(),Yii.app().getViewPath(),module.getViewPath());
- };
- /**
- * Finds a view file based on its name.
- * The view name can be in one of the following formats:
- * <ul>
- * <li>absolute view within a module: the view name starts with a single slash '/'.
- * In this case, the view will be searched for under the currently active module's view path.
- * If there is no active module, the view will be searched for under the application's view path.</li>
- * <li>absolute view within the application: the view name starts with double slashes '//'.
- * In this case, the view will be searched for under the application's view path.
- * This syntax has been available since version 1.1.3.</li>
- * <li>aliased view: the view name contains dots and refers to a path alias.
- * The view file is determined by calling {@link YiiBase::getPathOfAlias()}. Note that aliased views
- * cannot be themed because they can refer to a view file located at arbitrary places.</li>
- * <li>relative view: otherwise. Relative views will be searched for under the currently active
- * controller's view path.</li>
- * </ul>
- * For absolute view and relative view, the corresponding view file is a PHP file
- * whose name is the same as the view name. The file is located under a specified directory.
- * This method will call {@link CApplication::findLocalizedFile} to search for a localized file, if any.
- * @param {String} viewName the view name
- * @param {String} viewPath the directory that is used to search for a relative view name
- * @param {String} basePath the directory that is used to search for an absolute view name under the application
- * @param {String} moduleViewPath the directory that is used to search for an absolute view name under the current module.
- * If this is not set, the application base view path will be used.
- * @returns {Mixed} the view file path. False if the view file does not exist.
- * @since 1.0.3
- */
- Yii.CController.prototype.resolveViewFile = function (viewName, viewPath, basePath, moduleViewPath) {
- var renderer, extension, viewFile;
- if (moduleViewPath === undefined) {
- moduleViewPath = null;
- }
- if(php.empty(viewName)) {
- return false;
- }
- if(moduleViewPath===null) {
- moduleViewPath=basePath;
- }
- extension='.js';
-
- if(viewName[0]==='/') {
- if(php.strncmp(viewName,'//',2)===0) {
- viewFile=basePath+viewName.slice(1);
- }
- else {
- viewFile=moduleViewPath+viewName;
- }
- }
- else if(php.strpos(viewName,'.')) {
- viewFile=Yii.getPathOfAlias(viewName);
- }
- else {
- viewFile=viewPath+'/'+viewName;
- }
- return Yii.app().findLocalizedFile(viewFile+extension);
-
-
- };
- /**
- * Returns the list of clips.
- * A clip is a named piece of rendering result that can be
- * inserted at different places.
- * @returns {Yii.CMap} the list of clips
- * @see CClipWidget
- */
- Yii.CController.prototype.getClips = function () {
- if(this._clips!==null) {
- return this._clips;
- }
- else {
- return (this._clips=new Yii.CMap());
- }
- };
- /**
- * Processes the request using another controller action.
- * This is like {@link redirect}, but the user browser's URL remains unchanged.
- * In most cases, you should call {@link redirect} instead of this method.
- * @param {String} route the route of the new controller action. This can be an action ID, or a complete route
- * with module ID (optional in the current module), controller ID and action ID. If the former, the action is assumed
- * to be located within the current controller.
- * @param {Boolean} exit whether to end the application after this call. Defaults to true.
- * @since 1.1.0
- */
- Yii.CController.prototype.forward = function (route, exit) {
- var module;
- if (exit === undefined) {
- exit = true;
- }
- if(php.strpos(route,'/')===false) {
- this.run(route);
- }
- else
- {
- if(route[0]!=='/' && (module=this.getModule())!==null) {
- route=module.getId()+'/'+route;
- }
- Yii.app().runController(route);
- }
- if(exit) {
- Yii.app().end();
- }
- };
- /**
- * Renders a view with a layout.
- *
- * This method first calls {@link renderPartial} to render the view (called content view).
- * It then renders the layout view which may embed the content view at appropriate place.
- * In the layout view, the content view rendering result can be accessed via variable
- * <code>$content</code>. At the end, it calls {@link processOutput} to insert scripts
- * and dynamic contents if they are available.
- *
- * By default, the layout view script is "protected/views/layouts/main.php".
- * This may be customized by changing {@link layout}.
- *
- * @param {String} view name of the view to be rendered. See {@link getViewFile} for details
- * about how the view script is resolved.
- * @param {Array} data data to be extracted into PHP variables and made available to the view script
- * @param {Boolean} returnVar whether the rendering result should be returned instead of being displayed to end users.
- * @returns {String} the rendering result. Null if the rendering result is not required.
- * @see renderPartial
- * @see getLayoutFile
- */
- Yii.CController.prototype.render = function (viewAlias, data, callback) {
- var viewFile, self = this;
- if (data === undefined) {
- data = null;
- }
-
- if((viewFile=this.getViewFile(viewAlias))!==false) {
- return Yii.CView.prototype.load(viewFile, function (view) {
- if (typeof data === "object") {
- Yii.forEach(data, function (name, value) {
- view[name] = value;
- });
- if (self.beforeRender(view)) {
- view.render(function(html) {
- self.afterRender(view, html);
- return callback.apply(view, arguments);
- });
- }
- }
- });
- }
- else {
- throw new Yii.CException(Yii.t('yii','{controller} cannot find the requested view "{view}".',
- {'{controller}':php.get_class(this), '{view}':view}));
- }
- };
- /**
- * This method is invoked at the beginning of {@link render()}.
- * You may override this method to do some preprocessing when rendering a view.
- * @param {String} view the view to be rendered
- * @returns {Boolean} whether the view should be rendered.
- * @since 1.1.5
- */
- Yii.CController.prototype.beforeRender = function (view) {
- return true;
- };
- /**
- * This method is invoked after the specified is rendered by calling {@link render()}.
- * Note that this method is invoked BEFORE {@link processOutput()}.
- * You may override this method to do some postprocessing for the view rendering.
- * @param {String} view the view that has been rendered
- * @param {String} output the rendering result of the view. Note that this parameter is passed
- * as a reference. That means you can modify it within this method.
- * @since 1.1.5
- */
- Yii.CController.prototype.afterRender = function (view, output) {
- };
- /**
- * Renders a static text string.
- * The string will be inserted in the current controller layout and returned back.
- * @param {String} text the static text string
- * @param {Boolean} returnVar whether the rendering result should be returned instead of being displayed to end users.
- * @returns {String} the rendering result. Null if the rendering result is not required.
- * @see getLayoutFile
- */
- Yii.CController.prototype.renderText = function (text, returnVar) {
- var layoutFile;
- if (returnVar === undefined) {
- returnVar = false;
- }
- if((layoutFile=this.getLayoutFile(this.layout))!==false) {
- text=this.renderFile(layoutFile,{'content':text},true);
- }
- text=this.processOutput(text);
- if(returnVar) {
- return text;
- }
- else {
- $("body").append(text);
- }
- };
- /**
- * Renders a view.
- *
- * The named view refers to a PHP script (resolved via {@link getViewFile})
- * that is included by this method. If $data is an associative array,
- * it will be extracted as PHP variables and made available to the script.
- *
- * This method differs from {@link render()} in that it does not
- * apply a layout to the rendered result. It is thus mostly used
- * in rendering a partial view, or an AJAX response.
- *
- * @param {String} view name of the view to be rendered. See {@link getViewFile} for details
- * about how the view script is resolved.
- * @param {Array} data data to be made available to the view
- * @param {Function} callback The callback to execute with the rendering result
- * @returns {String} the rendering result. Null if the rendering result is not required.
- * @throws {Yii.CException} if the view does not exist
- * @see getViewFile
- * @see processOutput
- * @see render
- */
- Yii.CController.prototype.renderPartial = function (viewAlias, data, callback) {
- var viewFile;
- if (data === undefined) {
- data = null;
- }
- if((viewFile=this.getViewFile(viewAlias))!==false) {
- return Yii.CView.prototype.load(viewFile, function (view) {
- if (typeof data === "object") {
- Yii.forEach(data, function (name, value) {
- view[name] = value;
- });
- console.log(view);
- view.renderPartial(callback);
- }
- });
- return this.renderFile(viewFile,data,callback);
- }
- else {
- throw new Yii.CException(Yii.t('yii','{controller} cannot find the requested view "{view}".',
- {'{controller}':php.get_class(this), '{view}':view}));
- }
- };
- /**
- * Renders dynamic content returned by the specified callback.
- * This method is used together with {@link COutputCache}. Dynamic contents
- * will always show as their latest state even if the content surrounding them is being cached.
- * This is especially useful when caching pages that are mostly static but contain some small
- * dynamic regions, such as username or current time.
- * We can use this method to render these dynamic regions to ensure they are always up-to-date.
- *
- * The first parameter to this method should be a valid PHP callback, while the rest parameters
- * will be passed to the callback.
- *
- * Note, the callback and its parameter values will be serialized and saved in cache.
- * Make sure they are serializable.
- *
- * @param {Yii.Callback} callback a PHP callback which returns the needed dynamic content.
- * When the callback is specified as a string, it will be first assumed to be a method of the current
- * controller class. If the method does not exist, it is assumed to be a global PHP function.
- * Note, the callback should return the dynamic content instead of echoing it.
- */
- Yii.CController.prototype.renderDynamic = function (callback) {
- var n, params;
- n=php.count(this._dynamicOutput);
- document.write("<###dynamic-n###>");
- params=arguments;
- php.array_shift(params);
- this.renderDynamicInternal(callback,params);
- };
- /**
- * This method is internally used.
- * @param {Yii.Callback} callback a PHP callback which returns the needed dynamic content.
- * @param {Array} params parameters passed to the PHP callback
- * @see renderDynamic
- */
- Yii.CController.prototype.renderDynamicInternal = function (callback, params) {
- this.recordCachingAction('','renderDynamicInternal',[callback,params]);
- if(typeof(callback) === 'string' && php.method_exists(this,callback)) {
- callback=[this,callback];
- }
- this._dynamicOutput.push(php.call_user_func_array(callback,params));
- };
- /**
- * Creates a relative URL for the specified action defined in this controller.
- * @param {String} route the URL route. This should be in the format of 'ControllerID/ActionID'.
- * If the ControllerID is not present, the current controller ID will be prefixed to the route.
- * If the route is empty, it is assumed to be the current action.
- * Since version 1.0.3, if the controller belongs to a module, the {@link CWebModule::getId module ID}
- * will be prefixed to the route. (If you do not want the module ID prefix, the route should start with a slash '/'.)
- * @param {Array} params additional GET parameters (name=>value). Both the name and value will be URL-encoded.
- * If the name is '#', the corresponding value will be treated as an anchor
- * and will be appended at the end of the URL. This anchor feature has been available since version 1.0.1.
- * @param {String} ampersand the token separating name-value pairs in the URL.
- * @returns {String} the constructed URL
- */
- Yii.CController.prototype.createUrl = function (route, params, ampersand) {
- var module;
- if (params === undefined) {
- params = [];
- }
- if (ampersand === undefined) {
- ampersand = '&';
- }
- if(route==='') {
- route=this.getId()+'/'+this.getAction().getId();
- }
- else if(php.strpos(route,'/')===false) {
- route=this.getId()+'/'+route;
- }
- if(route[0]!=='/' && (module=this.getModule())!==null) {
- route=module.getId()+'/'+route;
- }
- return Yii.app().createUrl(php.trim(route,'/'),params,ampersand);
- };
- /**
- * Creates an absolute URL for the specified action defined in this controller.
- * @param {String} route the URL route. This should be in the format of 'ControllerID/ActionID'.
- * If the ControllerPath is not present, the current controller ID will be prefixed to the route.
- * If the route is empty, it is assumed to be the current action.
- * @param {Array} params additional GET parameters (name=>value). Both the name and value will be URL-encoded.
- * @param {String} schema schema to use (e.g. http, https). If empty, the schema used for the current request will be used.
- * @param {String} ampersand the token separating name-value pairs in the URL.
- * @returns {String} the constructed URL
- */
- Yii.CController.prototype.createAbsoluteUrl = function (route, params, schema, ampersand) {
- var url;
- if (params === undefined) {
- params = [];
- }
- if (schema === undefined) {
- schema = '';
- }
- if (ampersand === undefined) {
- ampersand = '&';
- }
- url=this.createUrl(route,params,ampersand);
- if(php.strpos(url,'http')===0) {
- return url;
- }
- else {
- return Yii.app().getRequest().getHostInfo(schema)+url;
- }
- };
- /**
- * @returns {String} the page title. Defaults to the controller name and the action name.
- */
- Yii.CController.prototype.getPageTitle = function () {
- var name;
- if(this._pageTitle!==null) {
- return this._pageTitle;
- }
- else {
- name=php.ucfirst(php.basename(this.getId()));
- if(this.getAction()!==null && php.strcasecmp(this.getAction().getId(),this.defaultAction)) {
- return (this._pageTitle=Yii.app().name+' - '+php.ucfirst(this.getAction().getId())+' '+name);
- }
- else {
- return (this._pageTitle=Yii.app().name+' - '+name);
- }
- }
- };
- /**
- * @param {String} value the page title.
- */
- Yii.CController.prototype.setPageTitle = function (value) {
- this._pageTitle=value;
- document.title = value;
- };
- /**
- * Redirects the browser to the specified URL or route (controller/action).
- * @param {Mixed} url the URL to be redirected to. If the parameter is an array,
- * the first element must be a route to a controller action and the rest
- * are GET parameters in name-value pairs.
- * @param {Boolean} terminate whether to terminate the current application after calling this method
- * @param {Integer} statusCode the HTTP status code. Defaults to 302. See {@link http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html}
- * for details about HTTP status code. This parameter has been available since version 1.0.4.
- */
- Yii.CController.prototype.redirect = function (url, terminate, statusCode) {
- var route;
- if (terminate === undefined) {
- terminate = true;
- }
- if (statusCode === undefined) {
- statusCode = 302;
- }
- if(Object.prototype.toString.call(url) === '[object Array]')
- {
- route=url[0] !== undefined ? url[0] : '';
- url=this.createUrl(route,php.array_splice(url,1));
- }
- Yii.app().getRequest().redirect(url,terminate,statusCode);
- };
- /**
- * Refreshes the current page.
- * The effect of this method call is the same as user pressing the
- * refresh button on the browser (without post data).
- * @param {Boolean} terminate whether to terminate the current application after calling this method
- * @param {String} anchor the anchor that should be appended to the redirection URL.
- * Defaults to empty. Make sure the anchor starts with '#' if you want to specify it.
- * The parameter has been available since version 1.0.7.
- */
- Yii.CController.prototype.refresh = function (terminate, anchor) {
- if (terminate === undefined) {
- terminate = true;
- }
- if (anchor === undefined) {
- anchor = '';
- }
- this.redirect(Yii.app().getRequest().getUrl()+anchor,terminate);
- };
- /**
- * Records a method call when an output cache is in effect.
- * When the content is served from the output cache, the recorded
- * method will be re-invoked.
- * @param {String} context a property name of the controller. It refers to an object
- * whose method is being called. If empty it means the controller itself.
- * @param {String} method the method name
- * @param {Array} params parameters passed to the method
- * @see COutputCache
- */
- Yii.CController.prototype.recordCachingAction = function (context, method, params) {
- var i, cache;
- if(this._cachingStack) {// record only when there is an active output cache
- for (i in this._cachingStack) {
- if (this._cachingStack.hasOwnProperty(i)) {
- cache = this._cachingStack[i];
- cache.recordAction(context,method,params);
- }
- }
- }
- };
- /**
- * @param {Boolean} createIfNull whether to create a stack if it does not exist yet. Defaults to true.
- * @returns {Yii.CStack} stack of {@link COutputCache} objects
- */
- Yii.CController.prototype.getCachingStack = function (createIfNull) {
- if (createIfNull === undefined) {
- createIfNull = true;
- }
- if(!this._cachingStack) {
- this._cachingStack=new Yii.CStack();
- }
- return this._cachingStack;
- };
- /**
- * Returns whether the caching stack is empty.
- * @returns {Boolean} whether the caching stack is empty. If not empty, it means currently there are
- * some output cache in effect. Note, the return result of this method may change when it is
- * called in different output regions, depending on the partition of output caches.
- * @since 1.0.5
- */
- Yii.CController.prototype.isCachingStackEmpty = function () {
- return this._cachingStack===null || !this._cachingStack.getCount();
- };
- /**
- * This method is invoked right before an action is to be executed (after all possible filters.)
- * You may override this method to do last-minute preparation for the action.
- * @param {Yii.CAction} action the action to be executed.
- * @returns {Boolean} whether the action should be executed.
- */
- Yii.CController.prototype.beforeAction = function (action) {
- return true;
- };
- /**
- * This method is invoked right after an action is executed.
- * You may override this method to do some postprocessing for the action.
- * @param {Yii.CAction} action the action just executed.
- */
- Yii.CController.prototype.afterAction = function (action) {
- };
- /**
- * The filter method for 'postOnly' filter.
- * This filter reports an error if the applied action is receiving a non-POST request.
- * @param {Yii.CFilterChain} filterChain the filter chain that the filter is on.
- * @throws {Yii.CHttpException} if the current request is not a POST request
- */
- Yii.CController.prototype.filterPostOnly = function (filterChain) {
- if(Yii.app().getRequest().getIsPostRequest()) {
- filterChain.run();
- }
- else {
- throw new Yii.CHttpException(400,Yii.t('yii','Your request is not valid.'));
- }
- };
- /**
- * The filter method for 'ajaxOnly' filter.
- * This filter reports an error if the applied action is receiving a non-AJAX request.
- * @param {Yii.CFilterChain} filterChain the filter chain that the filter is on.
- * @throws {Yii.CHttpException} if the current request is not an AJAX request.
- */
- Yii.CController.prototype.filterAjaxOnly = function (filterChain) {
- if(Yii.app().getRequest().getIsAjaxRequest()) {
- filterChain.run();
- }
- else {
- throw new Yii.CHttpException(400,Yii.t('yii','Your request is not valid.'));
- }
- };
- /**
- * The filter method for 'accessControl' filter.
- * This filter is a wrapper of {@link CAccessControlFilter}.
- * To use this filter, you must override {@link accessRules} method.
- * @param {Yii.CFilterChain} filterChain the filter chain that the filter is on.
- */
- Yii.CController.prototype.filterAccessControl = function (filterChain) {
- var filter;
- filter=new Yii.CAccessControlFilter();
- filter.setRules(this.accessRules());
- filter.filter(filterChain);
- };
- /**
- * Returns a persistent page state value.
- * A page state is a variable that is persistent across POST requests of the same page.
- * In order to use persistent page states, the form(s) must be stateful
- * which are generated using {@link CHtml::statefulForm}.
- * @param {String} name the state name
- * @param {Mixed} defaultValue the value to be returned if the named state is not found
- * @returns {Mixed} the page state value
- * @see setPageState
- * @see CHtml::statefulForm
- */
- Yii.CController.prototype.getPageState = function (name, defaultValue) {
- if (defaultValue === undefined) {
- defaultValue = null;
- }
- if(this._pageStates===null) {
- this._pageStates=this.loadPageStates();
- }
- return this._pageStates[name] !== undefined?this._pageStates[name]:defaultValue;
- };
- /**
- * Saves a persistent page state value.
- * A page state is a variable that is persistent across POST requests of the same page.
- * In order to use persistent page states, the form(s) must be stateful
- * which are generated using {@link CHtml::statefulForm}.
- * @param {String} name the state name
- * @param {Mixed} value the page state value
- * @param {Mixed} defaultValue the default page state value. If this is the same as
- * the given value, the state will be removed from persistent storage.
- * @see getPageState
- * @see CHtml::statefulForm
- */
- Yii.CController.prototype.setPageState = function (name, value, defaultValue) {
- var params;
- if (defaultValue === undefined) {
- defaultValue = null;
- }
- if(this._pageStates===null) {
- this._pageStates=this.loadPageStates();
- }
- if(value===defaultValue) {
- delete this._pageStates[name];
- }
- else {
- this._pageStates[name]=value;
- }
- params=arguments;
- this.recordCachingAction('','setPageState',params);
- };
- /**
- * Removes all page states.
- */
- Yii.CController.prototype.clearPageStates = function () {
- this._pageStates=[];
- };
- /**
- * Loads page states from a hidden input.
- * @returns {Object} the loaded page states
- */
- Yii.CController.prototype.loadPageStates = function () {
-
- return {};
- };
- /**
- * Saves page states as a base64 string.
- * @param {Array} states the states to be saved.
- * @param {String} output the output to be modified.
- * @returns {String} the modified output
- */
- Yii.CController.prototype.savePageStates = function (states, output) {
- var data, value;
- data=Yii.app().getSecurityManager().hashData(Yii.CJSON.encode(states));
-
- value=php.base64_encode(data);
- return php.str_replace(Yii.CHtml.pageStateField(''),Yii.CHtml.pageStateField(value),output);
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CFormModel represents a data model that collects HTML form inputs.
- *
- * Unlike {@link CActiveRecord}, the data collected by CFormModel are stored
- * in memory only, instead of database.
- *
- * To collect user inputs, you may extend CFormModel and define the attributes
- * whose values are to be collected from user inputs. You may override
- * {@link rules()} to declare validation rules that should be applied to
- * the attributes.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CFormModel.php 2799 2011-01-01 19:31:13Z qiang.xue $
- * @package system.web
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CModel
- */
- Yii.CFormModel = function CFormModel(scenario) {
- if (scenario !== false) {
- this.construct(scenario);
- }
- };
- Yii.CFormModel.prototype = new Yii.CModel();
- Yii.CFormModel.prototype.constructor = Yii.CFormModel;
- Yii.CFormModel.prototype._names = null;
- /**
- * Constructor.
- * @param {String} scenario name of the scenario that this model is used in.
- * See {@link CModel::scenario} on how scenario is used by models.
- * @see getScenario
- */
- Yii.CFormModel.prototype.construct = function (scenario) {
- if (scenario === undefined) {
- scenario = '';
- }
- this.setScenario(scenario);
- this.init();
- this.attachBehaviors(this.behaviors());
- this.afterConstruct();
- };
- /**
- * Initializes this model.
- * This method is invoked in the constructor right after {@link scenario} is set.
- * You may override this method to provide code that is needed to initialize the model (e.g. setting
- * initial property values.)
- * @since 1.0.8
- */
- Yii.CFormModel.prototype.init = function () {
- };
- /**
- * Returns the list of attribute names.
- * By default, this method returns all public properties of the class.
- * You may override this method to change the default.
- * @returns {Array} list of attribute names. Defaults to all public properties of the class.
- */
- Yii.CFormModel.prototype.attributeNames = function () {
- var i;
- if(this._names === null) {
- this._names=[];
- for (i in this) {
- if (this.hasOwnProperty(i) && i.slice(0,1) !== "_") {
- this._names.push(i);
- }
- }
- return this._names;
- }
- else {
- return this._names;
- }
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CHttpRequest encapsulates the $_SERVER variable and resolves its inconsistency among different Web servers.
- *
- * CHttpRequest also manages the cookies sent from and sent to the user.
- * By setting {@link enableCookieValidation} to true,
- * cookies sent from the user will be validated to see if they are tampered.
- * The property {@link getCookies cookies} returns the collection of cookies.
- * For more details, see {@link CCookieCollection}.
- *
- * CHttpRequest is a default application component loaded by {@link CWebApplication}. It can be
- * accessed via {@link CWebApplication::getRequest()}.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CHttpRequest.php 3050 2011-03-12 13:22:11Z qiang.xue $
- * @package system.web
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CApplicationComponent
- */
- Yii.CHttpRequest = function CHttpRequest () {
- };
- Yii.CHttpRequest.prototype = new Yii.CApplicationComponent();
- Yii.CHttpRequest.prototype.constructor = Yii.CHttpRequest;
- /**
- * @var {Boolean} whether cookies should be validated to ensure they are not tampered. Defaults to false.
- */
- Yii.CHttpRequest.prototype.enableCookieValidation = false;
- /**
- * @var {Boolean} whether to enable CSRF (Cross-Site Request Forgery) validation. Defaults to false.
- * By setting this property to true, forms submitted to an Yii Web application must be originated
- * from the same application. If not, a 400 HTTP exception will be raised.
- * Note, this feature requires that the user client accepts cookie.
- * You also need to use {@link CHtml::form} or {@link CHtml::statefulForm} to generate
- * the needed HTML forms in your pages.
- * @see http://seclab.stanford.edu/websec/csrf/csrf.pdf
- */
- Yii.CHttpRequest.prototype.enableCsrfValidation = false;
- /**
- * @var {String} the name of the token used to prevent CSRF. Defaults to 'YII_CSRF_TOKEN'.
- * This property is effectively only when {@link enableCsrfValidation} is true.
- */
- Yii.CHttpRequest.prototype.csrfTokenName = 'YII_CSRF_TOKEN';
- /**
- * @var {Object} the property values (in name-value pairs) used to initialize the CSRF cookie.
- * Any property of {@link CHttpCookie} may be initialized.
- * This property is effective only when {@link enableCsrfValidation} is true.
- */
- Yii.CHttpRequest.prototype.csrfCookie = null;
- /**
- * @var {Object} a list of GET parameters for this URL
- */
- Yii.CHttpRequest.prototype.params = {};
- Yii.CHttpRequest.prototype._requestUri = null;
- Yii.CHttpRequest.prototype._pathInfo = null;
- Yii.CHttpRequest.prototype._scriptFile = null;
- Yii.CHttpRequest.prototype._scriptUrl = null;
- Yii.CHttpRequest.prototype._hostInfo = null;
- Yii.CHttpRequest.prototype._baseUrl = null;
- Yii.CHttpRequest.prototype._cookies = null;
- Yii.CHttpRequest.prototype._preferredLanguage = null;
- Yii.CHttpRequest.prototype._csrfToken = null;
- Yii.CHttpRequest.prototype._deleteParams = null;
- Yii.CHttpRequest.prototype._putParams = null;
- Yii.CHttpRequest.prototype._port = null;
- Yii.CHttpRequest.prototype._securePort = null;
- /**
- * Initializes the application component.
- * This method overrides the parent implementation by preprocessing
- * the user request data.
- */
- Yii.CHttpRequest.prototype.init = function () {
- Yii.CApplicationComponent.prototype.init.call(this);
- this.normalizeRequest();
- };
- /**
- * Normalizes the request data.
- */
- Yii.CHttpRequest.prototype.normalizeRequest = function () {
- this.parseParams();
- };
- /**
- * Returns the named GET parameter value. POST is not supported because JavaScript doesn't have access to it.
- * If the GET parameter does not exist, the second parameter to this method will be returned.
- * @param {String} name the GET parameter name
- * @param {Mixed} defaultValue the default parameter value if the GET parameter does not exist.
- * @returns {Mixed} the GET parameter value
- * @since 1.0.4
- * @see getQuery
- */
- Yii.CHttpRequest.prototype.getParam = function (name, defaultValue) {
- if (this.params.hasOwnProperty(name)) {
- return this.params[name];
- }
- return defaultValue;
- };
- /**
- * Returns the named GET parameter value.
- * If the GET parameter does not exist, the second parameter to this method will be returned.
- * @param {String} name the GET parameter name
- * @param {Mixed} defaultValue the default parameter value if the GET parameter does not exist.
- * @returns {Mixed} the GET parameter value
- * @since 1.0.4
- * @see getPost
- * @see getParam
- */
- Yii.CHttpRequest.prototype.getQuery = function (name, defaultValue) {
- if (this.params.hasOwnProperty(name)) {
- return this.params[name];
- }
- return defaultValue;
- };
- /**
- * Parses the query string and adds the relevant GET variables to the list of parameters,
- * @see CHttpRequest.params
- * @returns {Object} The GET parameters key: value
- */
- Yii.CHttpRequest.prototype.parseParams = function () {
- var i, limit, matches, key, value;
- if (document.location.search.length === 0) {
- return false;
- }
- matches = document.location.search.slice(1).split("&");
- limit = matches.length;
- for (i = 0; i < limit; i++) {
- value = matches[i].split("=");
- key = value.shift();
- key = decodeURIComponent((key + '').replace(/\+/g, '%20'));
- value = decodeURIComponent((value.join("=") + '').replace(/\+/g, '%20'));
- this.params = this._setParamValue(key, value, this.params);
-
- }
- return this.params;
- };
- /**
- * Sets / parses a GET parameter, do not call this function directly
- * @see CHttpRequest.parseParams
- * @private
- *
- * @param {String} key The key to set
- * @param {mixed} value The value to set this key to
- * @param {Object} params The list of parameters to modify
- * @returns {Object} the modified list of parameters
- */
- Yii.CHttpRequest.prototype._setParamValue = function (key, value, params) {
- var parts, firstItem, secondItem, i, limit = 0;
- if (key.indexOf("[") === -1) {
- params[key] = value;
- return params;
- }
- parts = key.split("[");
- firstItem = parts.shift();
- if (firstItem.length === 0) {
- for (i in params) {
- if (params.hasOwnProperty(i)) {
- limit++;
- }
- }
- limit++;
- params[limit] = value;
- return params;
- }
- secondItem = parts.shift().split("]").shift();
- if (secondItem.length === 0) {
- limit = 0;
- for (i in params) {
- if (params.hasOwnProperty(i)) {
- limit++;
- }
- }
- limit++;
- secondItem = limit;
- }
- if (parts.length > 0) {
- parts = "[" + parts.join("[");
- }
- else {
- parts = "";
- }
- if (params[firstItem] === undefined) {
- params[firstItem] = {};
- }
-
- params[firstItem] = this._setParamValue(secondItem + parts, value, params[firstItem]);
- return params;
- };
- /**
- * Returns the currently requested URL.
- * This is the same as {@link getRequestUri}.
- * @returns {String} part of the request URL after the host info.
- */
- Yii.CHttpRequest.prototype.getUrl = function () {
- return this.getRequestUri();
- };
- /**
- * Returns the schema and host part of the application URL.
- * The returned URL does not have an ending slash.
- * By default this is determined based on the user request information.
- * You may explicitly specify it by setting the {@link setHostInfo hostInfo} property.
- * @param {String} schema schema to use (e.g. http, https). If empty, the schema used for the current request will be used.
- * @returns {String} schema and hostname part (with port number if needed) of the request URL (e.g. http://www.yiiframework.com)
- * @see setHostInfo
- */
- Yii.CHttpRequest.prototype.getHostInfo = function (schema) {
- var secure, http, port, pos;
- if (this._hostInfo === null) {
- secure = this.getIsSecureConnection();
- if (secure) {
- http = "https";
- }
- else {
- http = "http";
- }
- this._hostInfo = http + "://" + location.host;
- }
- if (schema !== undefined && schema !== null) {
- secure = this.getIsSecureConnection();
- if ((secure && schema === 'https') || (!secure && schema === 'http')) {
- return this._hostInfo;
- }
- port = this.getPort();
- if ((port !== 80 && schema === 'http') || (port !== 443 && schema === 'https')) {
- port = ':' + port;
- }
- else {
- port = '';
- }
- return this._hostInfo + port;
- }
- else {
- return this._hostInfo;
- }
- };
- /**
- * Sets the schema and host part of the application URL.
- * This setter is provided in case the schema and hostname cannot be determined
- * on certain Web servers.
- * @param {String} value the schema and host part of the application URL.
- */
- Yii.CHttpRequest.prototype.setHostInfo = function (value) {
- this._hostInfo=php.rtrim(value,'/');
- };
- /**
- * Returns the relative URL for the application.
- * This is similar to {@link getScriptUrl scriptUrl} except that
- * it does not have the script file name, and the ending slashes are stripped off.
- * @param {Boolean} absolute whether to return an absolute URL. Defaults to false, meaning returning a relative one.
- * This parameter has been available since 1.0.2.
- * @returns {String} the relative URL for the application
- * @see setScriptUrl
- */
- Yii.CHttpRequest.prototype.getBaseUrl = function (absolute) {
- if (absolute === undefined) {
- absolute = false;
- }
- if(this._baseUrl===null) {
- this._baseUrl=php.rtrim(php.dirname(this.getScriptUrl()),'\\/');
- }
- return absolute ? this.getHostInfo() + this._baseUrl : this._baseUrl;
- };
- /**
- * Sets the relative URL for the application.
- * By default the URL is determined based on the entry script URL.
- * This setter is provided in case you want to change this behavior.
- * @param {String} value the relative URL for the application
- */
- Yii.CHttpRequest.prototype.setBaseUrl = function (value) {
- this._baseUrl=value;
- };
- /**
- * Returns the relative URL of the entry script.
- * @returns {String} the relative URL of the entry script.
- */
- Yii.CHttpRequest.prototype.getScriptUrl = function () {
- if(this._scriptUrl===null) {
- this._scriptUrl = "";
- }
- return this._scriptUrl;
- };
- /**
- * Sets the relative URL for the application entry script.
- * This setter is provided in case the entry script URL cannot be determined
- * on certain Web servers.
- * @param {String} value the relative URL for the application entry script.
- */
- Yii.CHttpRequest.prototype.setScriptUrl = function (value) {
- this._scriptUrl='/'+php.trim(value,'/');
- };
- /**
- * Returns the path info of the currently requested URL.
- * This refers to the part that is after the entry script and before the question mark.
- * The starting and ending slashes are stripped off.
- * @returns {String} part of the request URL that is after the entry script and before the question mark.
- */
- Yii.CHttpRequest.prototype.getPathInfo = function () {
- if(this._pathInfo===null) {
- this._pathInfo = location.pathname;
- if (this._pathInfo.slice(0, 1) === "/") {
- this._pathInfo = this._pathInfo.slice(1);
- }
- if (this._pathInfo.slice(-1) === "/") {
- this._pathInfo = this._pathInfo.slice(0, -1);
- }
- }
- return this._pathInfo;
- };
- /**
- * Returns the request URI portion for the currently requested URL.
- * This refers to the portion that is after the {@link hostInfo host info} part.
- * It includes the {@link queryString query string} part if any.
- * The implementation of this method referenced Zend_Controller_Request_Http in Zend Framework.
- * @returns {String} the request URI portion for the currently requested URL.
- * @throws {Yii.CException} if the request URI cannot be determined due to improper server configuration
- * @since 1.0.1
- */
- Yii.CHttpRequest.prototype.getRequestUri = function () {
- if (this._requestUri === null) {
- this._requestUri = document.location.pathname + document.location.search;
- }
- return this._requestUri;
- };
- /**
- * Returns part of the request URL that is after the question mark.
- * @returns {String} part of the request URL that is after the question mark
- */
- Yii.CHttpRequest.prototype.getQueryString = function () {
- return location.search.length === 0 ? '' : location.search.slice(1);
- };
- /**
- * Return if the request is sent via secure channel (https).
- * @returns {Boolean} if the request is sent via secure channel (https)
- */
- Yii.CHttpRequest.prototype.getIsSecureConnection = function () {
- return location.protocol === "https:";
- };
- /**
- * Returns the request type. Always GET in this version.
- * @returns {String} request type, such as GET, POST, HEAD, PUT, DELETE.
- */
- Yii.CHttpRequest.prototype.getRequestType = function () {
- return "GET";
- };
- /**
- * Returns the server name.
- * @returns {String} server name
- */
- Yii.CHttpRequest.prototype.getServerName = function () {
- return location.host;
- };
- /**
- * Returns the server port number.
- * @returns {Integer} server port number
- */
- Yii.CHttpRequest.prototype.getServerPort = function () {
- return location.port;
- };
- /**
- * Returns the URL referrer, null if not present
- * @returns {String} URL referrer, null if not present
- */
- Yii.CHttpRequest.prototype.getUrlReferrer = function () {
- return document.referrer !== "" ? document.referrer :null;
- };
- /**
- * Returns the user agent, null if not present.
- * @returns {String} user agent, null if not present
- */
- Yii.CHttpRequest.prototype.getUserAgent = function () {
- return navigator.userAgent !== undefined && navigator.userAgent !== ''? navigator.userAgent : null;
- };
- /**
- * Doesn't return the user IP address because it's impossible without a server side call
- * @returns {String} user IP address
- */
- Yii.CHttpRequest.prototype.getUserHostAddress = function () {
- return null;
- };
- /**
- * Returns the user host name, null if it cannot be determined.
- * @returns {String} user host name, null if cannot be determined
- */
- Yii.CHttpRequest.prototype.getUserHost = function () {
- return null;
- };
- /**
- * Returns entry script file path.
- * @returns {String} entry script file path (processed w/ realpath())
- */
- Yii.CHttpRequest.prototype.getScriptFile = function () {
- if(this._scriptFile!==null) {
- return this._scriptFile;
- }
- else {
- return (this._scriptFile="/");
- }
- };
- /**
- * Returns user browser accept types, null if not present.
- * @returns {String} user browser accept types, null if not present
- */
- Yii.CHttpRequest.prototype.getAcceptTypes = function () {
- return null;
- };
- /**
- * Returns the port to use for insecure requests.
- * Defaults to 80, or the port specified by the server if the current
- * request is insecure.
- * You may explicitly specify it by setting the {@link setPort port} property.
- * @returns {Integer} port number for insecure requests.
- * @see setPort
- * @since 1.1.3
- */
- Yii.CHttpRequest.prototype.getPort = function () {
- if(this._port===null) {
- if (location.port === '') {
- if (this.getIsSecureConnection()) {
- this._port = 443;
- }
- else {
- this._port = 80;
- }
- }
- }
- return this._port;
- };
- /**
- * Sets the port to use for insecure requests.
- * This setter is provided in case a custom port is necessary for certain
- * server configurations.
- * @param {Integer} value port number.
- * @since 1.1.3
- */
- Yii.CHttpRequest.prototype.setPort = function (value) {
- this._port=Number(value);
- this._hostInfo=null;
- };
- /**
- * Returns the port to use for secure requests.
- * Defaults to 443, or the port specified by the server if the current
- * request is secure.
- * You may explicitly specify it by setting the {@link setSecurePort securePort} property.
- * @returns {Integer} port number for secure requests.
- * @see setSecurePort
- * @since 1.1.3
- */
- Yii.CHttpRequest.prototype.getSecurePort = function () {
- if(this._securePort===null) {
- this._securePort=this.getIsSecureConnection() && location.port !== '' ? Number(location.port) : 443;
- }
- return this._securePort;
- };
- /**
- * Sets the port to use for secure requests.
- * This setter is provided in case a custom port is necessary for certain
- * server configurations.
- * @param {Integer} value port number.
- * @since 1.1.3
- */
- Yii.CHttpRequest.prototype.setSecurePort = function (value) {
- this._securePort=Number(value);
- this._hostInfo=null;
- };
- /**
- * Returns the cookie collection.
- * The result can be used like an associative array. Adding {@link CHttpCookie} objects
- * to the collection will send the cookies to the client; and removing the objects
- * from the collection will delete those cookies on the client.
- * @returns {Yii.CCookieCollection} the cookie collection.
- */
- Yii.CHttpRequest.prototype.getCookies = function () {
- if(this._cookies!==null) {
- return this._cookies;
- }
- else {
- return (this._cookies=new Yii.CCookieCollection(this));
- }
- };
- /**
- * Redirects the browser to the specified URL.
- * @param {String} url URL to be redirected to. If the URL is a relative one, the base URL of
- * the application will be inserted at the beginning.
- * @param {Boolean} terminate whether to terminate the current application
- * @param {Integer} statusCode the HTTP status code. Defaults to 302. See {@link http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html}
- * for details about HTTP status code. This parameter has been available since version 1.0.4.
- */
- Yii.CHttpRequest.prototype.redirect = function (url, terminate, statusCode) {
- if (terminate === undefined) {
- terminate = true;
- }
- if (statusCode === undefined) {
- statusCode = 302;
- }
- if(php.strpos(url,'/')===0) {
- url=this.getHostInfo()+url;
- }
- document.location = url;
- if(terminate) {
- Yii.app().end();
- }
- };
- /**
- * Returns the user preferred language.
- * The returned language ID will be canonicalized using {@link CLocale::getCanonicalID}.
- * This method returns false if the user does not have language preference.
- * @returns {String} the user preferred language.
- */
- Yii.CHttpRequest.prototype.getPreferredLanguage = function () {
- if(this._preferredLanguage===null) {
- return (this._preferredLanguage=Yii.CLocale.getCanonicalID(navigator.language));
- }
- return this._preferredLanguage;
- };
- /**
- * Returns the random token used to perform CSRF validation.
- * The token will be read from cookie first. If not found, a new token
- * will be generated.
- * @returns {String} the random token for CSRF validation.
- * @see enableCsrfValidation
- */
- Yii.CHttpRequest.prototype.getCsrfToken = function () {
-
- return this._csrfToken;
- };
- /**
- * Determine whether this is an AJAX request, always false.
- * @returns {Boolean} false
- */
- Yii.CHttpRequest.prototype.getIsAjaxRequest = function () {
- return false;
- };
- /*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CLayoutView is a base class for layouts
- *
- * @package system.web
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CComponent
- */
- Yii.CLayoutView = function CLayoutView (config) {
- if (config !== false) {
- this.template = null;
- this.construct(config);
- }
- };
- Yii.CLayoutView.prototype = new Yii.CView(false);
- Yii.CLayoutView.prototype.constructor = Yii.CLayoutView;
- /**
- * The content to render
- * @var String
- */
- Yii.CLayoutView.prototype.content = "";
-
- /**
- * The template to render
- * @var String
- */
- Yii.CLayoutView.prototype.templateURL = "application.views.layouts.main";
-
- /**
- * Gets the page title
- * @returns {String} The page title
- */
- Yii.CLayoutView.prototype.pageTitle = function () {
- return Yii.app().getController().getPageTitle();
- };
-
-
- /**
- * Displays the breadcrumbs
- * @returns {String} The html for the main menu
- */
- Yii.CLayoutView.prototype.breadcrumbs = function () {
- var crumbs, links;
- if (Yii.app().getController().breadcrumbs !== undefined) {
- links = Yii.app().getController().breadcrumbs;
- if (links.length === 0) {
- return "";
- }
- crumbs = new Yii.CBreadcrumbs;
- crumbs.links = links;
- return crumbs.run();
- }
- return "";
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CUrlManager manages the URLs of Yii Web applications.
- *
- * It provides URL construction ({@link createUrl()}) as well as parsing ({@link parseUrl()}) functionality.
- *
- * URLs managed via CUrlManager can be in one of the following two formats,
- * by setting {@link setUrlFormat urlFormat} property:
- * <ul>
- * <li>'path' format: /path/to/EntryScript.php/name1/value1/name2/value2...</li>
- * <li>'get' format: /path/to/EntryScript.php?name1=value1&name2=value2...</li>
- * </ul>
- *
- * When using 'path' format, CUrlManager uses a set of {@link setRules rules} to:
- * <ul>
- * <li>parse the requested URL into a route ('ControllerID/ActionID') and GET parameters;</li>
- * <li>create URLs based on the given route and GET parameters.</li>
- * </ul>
- *
- * A rule consists of a route and a pattern. The latter is used by CUrlManager to determine
- * which rule is used for parsing/creating URLs. A pattern is meant to match the path info
- * part of a URL. It may contain named parameters using the syntax '<ParamName:RegExp>'.
- *
- * When parsing a URL, a matching rule will extract the named parameters from the path info
- * and put them into the Yii.app().getRequest.params variable; when creating a URL, a matching rule will extract
- * the named parameters from Yii.app().getRequest.params and put them into the path info part of the created URL.
- *
- * If a pattern ends with '/ *', it means additional GET parameters may be appended to the path
- * info part of the URL; otherwise, the GET parameters can only appear in the query string part.
- *
- * To specify URL rules, set the {@link setRules rules} property as an array of rules (pattern=>route).
- * For example,
- * <pre>
- * {
- * 'articles':'article/list',
- * 'article/<id:\d+>/ *':'article/read',
- * }
- * </pre>
- * Two rules are specified in the above:
- * <ul>
- * <li>The first rule says that if the user requests the URL '/path/to/index.php/articles',
- * it should be treated as '/path/to/index.php/article/list'; and vice versa applies
- * when constructing such a URL.</li>
- * <li>The second rule contains a named parameter 'id' which is specified using
- * the <ParamName:RegExp> syntax. It says that if the user requests the URL
- * '/path/to/index.php/article/13', it should be treated as '/path/to/index.php/article/read?id=13';
- * and vice versa applies when constructing such a URL.</li>
- * </ul>
- *
- * Starting from version 1.0.5, the route part may contain references to named parameters defined
- * in the pattern part. This allows a rule to be applied to different routes based on matching criteria.
- * For example,
- * <pre>
- * {
- * '<_c:(post|comment)>/<id:\d+>/<_a:(create|update|delete)>':'<_c>/<_a>',
- * '<_c:(post|comment)>/<id:\d+>':'<_c>/view',
- * '<_c:(post|comment)>s/ *':'<_c>/list',
- * }
- * </pre>
- * In the above, we use two named parameters '<_c>' and '<_a>' in the route part. The '<_c>'
- * parameter matches either 'post' or 'comment', while the '<_a>' parameter matches an action ID.
- *
- * Like normal rules, these rules can be used for both parsing and creating URLs.
- * For example, using the rules above, the URL '/index.php/post/123/create'
- * would be parsed as the route 'post/create' with GET parameter 'id' being 123.
- * And given the route 'post/list' and GET parameter 'page' being 2, we should get a URL
- * '/index.php/posts/page/2'.
- *
- * Starting from version 1.0.11, it is also possible to include hostname into the rules
- * for parsing and creating URLs. One may extract part of the hostname to be a GET parameter.
- * For example, the URL <code>http://admin.example.com/en/profile</code> may be parsed into GET parameters
- * <code>user=admin</code> and <code>lang=en</code>. On the other hand, rules with hostname may also be used to
- * create URLs with parameterized hostnames.
- *
- * In order to use parameterized hostnames, simply declare URL rules with host info, e.g.:
- * <pre>
- * {
- * 'http://<user:\w+>.example.com/<lang:\w+>/profile' : 'user/profile',
- * }
- * </pre>
- *
- * CUrlManager is a default application component that may be accessed via
- * {@link CWebApplication::getUrlManager()}.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CUrlManager.php 3165 2011-04-06 08:27:40Z mdomba $
- * @package system.web
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CApplicationComponent
- */
- Yii.CUrlManager = function CUrlManager () {
- };
- Yii.CUrlManager.prototype = new Yii.CApplicationComponent();
- Yii.CUrlManager.prototype.constructor = Yii.CUrlManager;
- /**
- * @const
- */
- Yii.CUrlManager.prototype.CACHE_KEY = 'Yii.CUrlManager.rules';
- /**
- * @const
- */
- Yii.CUrlManager.prototype.GET_FORMAT = 'get';
- /**
- * @const
- */
- Yii.CUrlManager.prototype.PATH_FORMAT = 'path';
- /**
- * @var {Array} an array of url rule configurations
- */
- Yii.CUrlManager.prototype.rules = [];
- /**
- * @var {String} the URL suffix used when in 'path' format.
- * For example, ".html" can be used so that the URL looks like pointing to a static HTML page. Defaults to empty.
- */
- Yii.CUrlManager.prototype.urlSuffix = '';
- /**
- * @var {Boolean} whether to show entry script name in the constructed URL. Defaults to true.
- */
- Yii.CUrlManager.prototype.showScriptName = true;
- /**
- * @var {Boolean} whether to append GET parameters to the path info part. Defaults to true.
- * This property is only effective when {@link urlFormat} is 'path' and is mainly used when
- * creating URLs. When it is true, GET parameters will be appended to the path info and
- * separate from each other using slashes. If this is false, GET parameters will be in query part.
- * @since 1.0.3
- */
- Yii.CUrlManager.prototype.appendParams = true;
- /**
- * @var {String} the GET variable name for route. Defaults to 'r'.
- */
- Yii.CUrlManager.prototype.routeVar = 'r';
- /**
- * @var {Boolean} whether routes are case-sensitive. Defaults to true. By setting this to false,
- * the route in the incoming request will be turned to lower case first before further processing.
- * As a result, you should follow the convention that you use lower case when specifying
- * controller mapping ({@link CWebApplication::controllerMap}) and action mapping
- * ({@link CController::actions}). Also, the directory names for organizing controllers should
- * be in lower case.
- * @since 1.0.1
- */
- Yii.CUrlManager.prototype.caseSensitive = true;
- /**
- * @var {Boolean} whether the GET parameter values should match the corresponding
- * sub-patterns in a rule before using it to create a URL. Defaults to false, meaning
- * a rule will be used for creating a URL only if its route and parameter names match the given ones.
- * If this property is set true, then the given parameter values must also match the corresponding
- * parameter sub-patterns. Note that setting this property to true will degrade performance.
- * @since 1.1.0
- */
- Yii.CUrlManager.prototype.matchValue = false;
- /**
- * @var {String} the ID of the cache application component that is used to cache the parsed URL rules.
- * Defaults to 'cache' which refers to the primary cache application component.
- * Set this property to false if you want to disable caching URL rules.
- * @since 1.0.3
- */
- Yii.CUrlManager.prototype.cacheID = 'cache';
- /**
- * @var {Boolean} whether to enable strict URL parsing.
- * This property is only effective when {@link urlFormat} is 'path'.
- * If it is set true, then an incoming URL must match one of the {@link rules URL rules}.
- * Otherwise, it will be treated as an invalid request and trigger a 404 HTTP exception.
- * Defaults to false.
- * @since 1.0.6
- */
- Yii.CUrlManager.prototype.useStrictParsing = false;
- Yii.CUrlManager.prototype._urlFormat = 'get';
- Yii.CUrlManager.prototype._rules = [];
- Yii.CUrlManager.prototype._baseUrl = null;
- /**
- * Initializes the application component.
- */
- Yii.CUrlManager.prototype.init = function () {
- Yii.CApplicationComponent.prototype.init.call(this);
- this.processRules();
- };
- /**
- * Processes the URL rules.
- */
- Yii.CUrlManager.prototype.processRules = function () {
- var cache, hash, data, route, pattern, i, limit;
- if(php.empty(this.rules) || this.getUrlFormat()===this.GET_FORMAT) {
- return;
- }
- limit = this.rules.length;
- for (i = 0; i < limit; i++) {
- route = this.rules[i];
- this._rules.push(this.createUrlRule(route, route.pattern));
- }
- if(cache !== undefined) {
- cache.set(this.Yii.CACHE_KEY,[this._rules,hash]);
- }
- };
- /**
- * Adds new URL rules.
- * In order to make the new rules effective, this method must be called BEFORE
- * {@link CWebApplication::processRequest}.
- * @param {Array} rules new URL rules (pattern=>route).
- * @since 1.1.4
- */
- Yii.CUrlManager.prototype.addRules = function (rules) {
- var route, pattern;
- for (pattern in rules) {
- if (rules.hasOwnProperty(pattern)) {
- route = rules[pattern];
- this._rules.push(this.createUrlRule(route,pattern));
- }
- }
- };
- /**
- * Creates a URL rule instance.
- * The default implementation returns a CUrlRule object.
- * @param {Mixed} route the route part of the rule. This could be a string or an array
- * @param {String} pattern the pattern part of the rule
- * @returns {Yii.CUrlRule} the URL rule instance
- * @since 1.1.0
- */
- Yii.CUrlManager.prototype.createUrlRule = function (route, pattern) {
- return new Yii.CUrlRule(route,pattern);
- };
- /**
- * Constructs a URL.
- * @param {String} route the controller and the action (e.g. article/read)
- * @param {Array} params list of GET parameters (name=>value). Both the name and value will be URL-encoded.
- * If the name is '#', the corresponding value will be treated as an anchor
- * and will be appended at the end of the URL. This anchor feature has been available since version 1.0.1.
- * @param {String} ampersand the token separating name-value pairs in the URL. Defaults to '&'.
- * @returns {String} the constructed URL
- */
- Yii.CUrlManager.prototype.createUrl = function (route, params, ampersand) {
- var i, param, anchor, n, url, rule;
- if (params === undefined) {
- params = [];
- }
- if (ampersand === undefined) {
- ampersand = '&';
- }
- delete params[this.routeVar];
- for (i in params) {
- if (params.hasOwnProperty(i)) {
- if(params[i]===null) {
- params[i]='';
- }
- }
- }
- if(params['#'] !== undefined) {
- anchor='#'+params['#'];
- delete params['#'];
- }
- else {
- anchor='';
- }
- route=php.trim(route,'/');
- for (n in this._rules) {
- if (this._rules.hasOwnProperty(n)) {
- rule = this._rules[n];
- if((url=rule.createUrl(this,route,params,ampersand))!==false) {
- if(rule.hasHostInfo) {
- return url==='' ? '/'+anchor : url+anchor;
- }
- else {
- return this.getBaseUrl()+'/'+url+anchor;
- }
- }
- }
- }
- return this.createUrlDefault(route,params,ampersand)+anchor;
- };
- /**
- * Contructs a URL based on default settings.
- * @param {String} route the controller and the action (e.g. article/read)
- * @param {Array} params list of GET parameters
- * @param {String} ampersand the token separating name-value pairs in the URL.
- * @returns {String} the constructed URL
- */
- Yii.CUrlManager.prototype.createUrlDefault = function (route, params, ampersand) {
- var url, query;
- if(this.getUrlFormat()===this.PATH_FORMAT) {
- url=php.rtrim(this.getBaseUrl()+'/'+route,'/');
- if(this.appendParams) {
- url=php.rtrim(url+'/'+this.createPathInfo(params,'/','/'),'/');
- return route==='' ? url : url+this.urlSuffix;
- }
- else {
- if(route!=='') {
- url+=this.urlSuffix;
- }
- query=this.createPathInfo(params,'=',ampersand);
- return query==='' ? url : url+'?'+query;
- }
- }
- else
- {
- url=this.getBaseUrl();
- if(!this.showScriptName) {
- url+='/';
- }
- if(route!=='') {
- url+='?'+this.routeVar+'='+route;
- if((query=this.createPathInfo(params,'=',ampersand))!=='') {
- url+=ampersand+query;
- }
- }
- else if((query=this.createPathInfo(params,'=',ampersand))!=='') {
- url+='?'+query;
- }
- return url;
- }
- };
- /**
- * Parses the user request.
- * @param {Yii.CHttpRequest} request the request application component
- * @returns {String} the route (controllerID/actionID) and perhaps GET parameters in path format.
- */
- Yii.CUrlManager.prototype.parseUrl = function (request) {
- var rawPathInfo, pathInfo, i, r, rule;
- if(this.getUrlFormat()===this.PATH_FORMAT) {
- rawPathInfo=request.getPathInfo();
- pathInfo=this.removeUrlSuffix(rawPathInfo,this.urlSuffix);
- for (i in this._rules) {
- if (this._rules.hasOwnProperty(i)) {
- rule = this._rules[i];
-
- if((r=rule.parseUrl(this,request,pathInfo,rawPathInfo))!==false) {
-
- return Yii.app().getRequest().params[this.routeVar] !== undefined ? Yii.app().getRequest().params[this.routeVar] : r;
- }
- }
- }
- if(this.useStrictParsing) {
- throw new Yii.CHttpException(404,Yii.t('yii','Unable to resolve the request "{route}".',
- {'{route}':pathInfo}));
- }
- else {
- return pathInfo;
- }
- }
- else if(Yii.app().getRequest().params[this.routeVar] !== undefined) {
- return Yii.app().getRequest().params[this.routeVar];
- }
- else {
- return '';
- }
- };
- /**
- * Parses a path info into URL segments and saves them to Yii.app().getRequest.params
- * @param {String} pathInfo path info
- * @since 1.0.3
- */
- Yii.CUrlManager.prototype.parsePathInfo = function (pathInfo) {
- var segs, n, i, key, value, pos, m, matches, name, j, val;
- if(pathInfo==='') {
- return;
- }
- segs=pathInfo+'/'.split('/');
- n=php.count(segs);
- for(i=0;i<n-1;i+=2) {
- key=segs[i];
- if(key==='') {
- continue;
- }
- value=segs[i+1];
- if((pos=php.strpos(key,'['))!==false && (matches=key.match(/\[(.*?)\]/g)) !== null) {
- name=key.slice(0, pos);
- for(j=m-1;j>=0;--j) {
- if(matches[1][j]==='') {
- value=[value];
- }
- else {
- val = {};
- val[matches[1][j]] = value;
- value = val;
- }
- }
- if(Yii.app().getRequest.params[name] !== undefined && typeof Yii.app().getRequest.params[name] === 'object') {
- value=Yii.CMap.prototype.mergeArray(Yii.app().getRequest.params[name],value);
- }
- Yii.app().getRequest.params[name]=value;
- }
- else {
- Yii.app().getRequest.params[key]=value;
- }
- }
- };
- /**
- * Creates a path info based on the given parameters.
- * @param {Array} params list of GET parameters
- * @param {String} equal the separator between name and value
- * @param {String} ampersand the separator between name-value pairs
- * @param {String} key this is used internally.
- * @returns {String} the created path info
- * @since 1.0.3
- */
- Yii.CUrlManager.prototype.createPathInfo = function (params, equal, ampersand, key) {
- var pairs, k, v;
- if (key === undefined) {
- key = null;
- }
- pairs = [];
- for (k in params) {
- if (params.hasOwnProperty(k)) {
- v = params[k];
- if (key!==null) {
- k = key+'['+k+']';
- }
- if (typeof v === "object") {
- pairs.push(this.createPathInfo(v,equal,ampersand, k));
- }
- else {
- pairs.push(php.urlencode(k)+equal+php.urlencode(v));
- }
- }
- }
- return pairs.join(ampersand);
- };
- /**
- * Removes the URL suffix from path info.
- * @param {String} pathInfo path info part in the URL
- * @param {String} urlSuffix the URL suffix to be removed
- * @returns {String} path info with URL suffix removed.
- */
- Yii.CUrlManager.prototype.removeUrlSuffix = function (pathInfo, urlSuffix) {
- if(urlSuffix!=='' && pathInfo.slice(-php.strlen(urlSuffix))===urlSuffix) {
- return pathInfo.slice(0, -php.strlen(urlSuffix));
- }
- else {
- return pathInfo;
- }
- };
- /**
- * Returns the base URL of the application.
- * @returns {String} the base URL of the application (the part after host name and before query string).
- * If {@link showScriptName} is true, it will include the script name part.
- * Otherwise, it will not, and the ending slashes are stripped off.
- */
- Yii.CUrlManager.prototype.getBaseUrl = function () {
- if(this._baseUrl!==null) {
- return this._baseUrl;
- }
- else
- {
- if(this.showScriptName) {
- this._baseUrl=Yii.app().getRequest().getScriptUrl();
- }
- else {
- this._baseUrl=Yii.app().getRequest().getBaseUrl();
- }
- return this._baseUrl;
- }
- };
- /**
- * Sets the base URL of the application (the part after host name and before query string).
- * This method is provided in case the {@link baseUrl} cannot be determined automatically.
- * The ending slashes should be stripped off. And you are also responsible to remove the script name
- * if you set {@link showScriptName} to be false.
- * @param {String} value the base URL of the application
- * @since 1.1.1
- */
- Yii.CUrlManager.prototype.setBaseUrl = function (value) {
- this._baseUrl=value;
- };
- /**
- * Returns the URL format.
- * @returns {String} the URL format. Defaults to 'path'. Valid values include 'path' and 'get'.
- * Please refer to the guide for more details about the difference between these two formats.
- */
- Yii.CUrlManager.prototype.getUrlFormat = function () {
- return this._urlFormat;
- };
- /**
- * Sets the URL format.
- * @param {String} value the URL format. It must be either 'path' or 'get'.
- */
- Yii.CUrlManager.prototype.setUrlFormat = function (value) {
- if(value===this.PATH_FORMAT || value===this.GET_FORMAT) {
- this._urlFormat=value;
- }
- else {
- throw new Yii.CException(Yii.t('yii','CUrlManager.UrlFormat must be either "path" or "get".'));
- }
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CUrlRule represents a URL formatting/parsing rule.
- *
- * It mainly consists of two parts: route and pattern. The former classifies
- * the rule so that it only applies to specific controller-action route.
- * The latter performs the actual formatting and parsing role. The pattern
- * may have a set of named parameters.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CUrlManager.php 3165 2011-04-06 08:27:40Z mdomba $
- * @package system.web
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CComponent
- */
- Yii.CUrlRule = function CUrlRule (route, pattern) {
- if (route !== false) {
- this.construct(route, pattern);
- }
- };
- Yii.CUrlRule.prototype = new Yii.CComponent();
- Yii.CUrlRule.prototype.constructor = Yii.CUrlRule;
- /**
- * @var {String} the URL suffix used for this rule.
- * For example, ".html" can be used so that the URL looks like pointing to a static HTML page.
- * Defaults to null, meaning using the value of {@link CUrlManager::urlSuffix}.
- * @since 1.0.6
- */
- Yii.CUrlRule.prototype.urlSuffix = null;
- /**
- * @var {Boolean} whether the rule is case sensitive. Defaults to null, meaning
- * using the value of {@link CUrlManager::caseSensitive}.
- * @since 1.0.1
- */
- Yii.CUrlRule.prototype.caseSensitive = null;
- /**
- * @var {Object} the default GET parameters (name=>value) that this rule provides.
- * When this rule is used to parse the incoming request, the values declared in this property
- * will be injected into Yii.app().getRequest().params
- * @since 1.0.8
- */
- Yii.CUrlRule.prototype.defaultParams = {};
- /**
- * @var {Boolean} whether the GET parameter values should match the corresponding
- * sub-patterns in the rule when creating a URL. Defaults to null, meaning using the value
- * of {@link CUrlManager::matchValue}. When this property is false, it means
- * a rule will be used for creating a URL if its route and parameter names match the given ones.
- * If this property is set true, then the given parameter values must also match the corresponding
- * parameter sub-patterns. Note that setting this property to true will degrade performance.
- * @since 1.1.0
- */
- Yii.CUrlRule.prototype.matchValue = null;
- /**
- * @var {String} the HTTP verb (e.g. GET, POST, DELETE) that this rule should match.
- * If this rule can match multiple verbs, please separate them with commas.
- * If this property is not set, the rule can match any verb.
- * Note that this property is only used when parsing a request. It is ignored for URL creation.
- * @since 1.1.7
- */
- Yii.CUrlRule.prototype.verb = null;
- /**
- * @var {Boolean} whether this rule is only used for request parsing.
- * Defaults to false, meaning the rule is used for both URL parsing and creation.
- * @since 1.1.7
- */
- Yii.CUrlRule.prototype.parsingOnly = false;
- /**
- * @var {String} the controller/action pair
- */
- Yii.CUrlRule.prototype.route = null;
- /**
- * @var {Object} the mapping from route param name to token name (e.g. _r1=><1>)
- * @since 1.0.5
- */
- Yii.CUrlRule.prototype.references = {};
- /**
- * @var {String} the pattern used to match route
- * @since 1.0.5
- */
- Yii.CUrlRule.prototype.routePattern = null;
- /**
- * @var {String} regular expression used to parse a URL
- */
- Yii.CUrlRule.prototype.pattern = null;
- /**
- * @var {String} template used to construct a URL
- */
- Yii.CUrlRule.prototype.template = null;
- /**
- * @var {Object} list of parameters (name=>regular expression)
- */
- Yii.CUrlRule.prototype.params = {};
- /**
- * @var {Boolean} whether the URL allows additional parameters at the end of the path info.
- */
- Yii.CUrlRule.prototype.append = null;
- /**
- * @var {Boolean} whether host info should be considered for this rule
- * @since 1.0.11
- */
- Yii.CUrlRule.prototype.hasHostInfo = null;
- /**
- * Constructor.
- * @param {String} route the route of the URL (controller/action)
- * @param {String} pattern the pattern for matching the URL
- */
- Yii.CUrlRule.prototype.construct = function (route, pattern) {
- var i, name, tr2 = {}, tr = {}, matches2, n, matches, tokens, value, p, vals, limit;
- this.references = {};
- this.defaultParams = {};
- this.params = {};
- if(typeof route === 'object') {
- vals = ['urlSuffix','caseSensitive','defaultParams','matchValue','verb','parsingOnly'];
- limit = vals.length;
- for (i = 0; i < limit; i ++) {
- name = vals[i];
- if(route[name] !== undefined) {
- this[name]=route[name];
- }
- }
-
- if(route.pattern !== undefined) {
- pattern=route.pattern;
- }
- route=route.route;
- }
- this.route=php.trim(route,'/');
- tr2['/']=tr['/']='\\/';
- if(php.strpos(route,'<')!==false) {
- matches2 = Yii.matchAll(/<(\w+)>/g, route);
- limit = matches2.length;
- for (n in matches2) {
- if (matches2.hasOwnProperty(n)) {
- this.references[matches2[n][1]] = "<" + matches2[n][1] + ">";
- }
- }
- }
- this.hasHostInfo=!php.strncasecmp(pattern,'http://',7) || !php.strncasecmp(pattern,'https://',8);
- if(this.verb!==null) {
- this.verb=this.verb.toUpperCase().split(/[\s,]+/);
- }
-
- matches = Yii.matchAll(/<(\w+):?(.*?)?>/g, pattern);
-
- if (matches !== null) {
- for (i in matches) {
- if (matches.hasOwnProperty(i)) {
- if (matches[i][2] === '') {
- matches[i][2] = '[^\/]+';
- }
- tr["<" + matches[i][1] + ">"] = "(" + matches[i][2] + ")";
- if (this.references[matches[i][1]] !== undefined) {
-
- tr2["<" + matches[i][1] + ">"] = tr["<" + matches[i][1] + ">"];
-
- }
- else {
-
- this.params[matches[i][1]] = matches[i][2];
- }
- }
- }
- }
- p=php.rtrim(pattern,'*');
- this.append=p!==pattern;
- p=php.trim(p,'/');
- this.template=p.replace(/<(\w+):?.*?>/g,'<$1>');
- this.pattern='^'+php.strtr(this.template,tr) + "\/";
- if(!this.append) {
- this.pattern+='$';
- }
- limit = 0;
-
- for (i in this.references) {
- if (this.references.hasOwnProperty(i)) {
- limit++;
- }
- }
- if (limit > 0) {
-
- this.routePattern = "^" + php.strtr(this.route, tr2) + "$";
- }
-
- };
- /**
- * Creates a URL based on this rule.
- * @param {Yii.CUrlManager} manager the manager
- * @param {String} route the route
- * @param {Array} params list of parameters
- * @param {String} ampersand the token separating name-value pairs in the URL.
- * @returns {Mixed} the constructed URL or false on error
- */
- Yii.CUrlRule.prototype.createUrl = function (manager, route, params, ampersand) {
- var caseVar, tr, matches, name, key, value, suffix, url, hostInfo, n;
- if(this.parsingOnly) {
- return false;
- }
- if(manager.caseSensitive && this.caseSensitive===null || this.caseSensitive) {
- caseVar='';
- }
- else {
- caseVar='i';
- }
- tr={};
-
- if(route!==this.route) {
-
- if(this.routePattern!==null && ((matches = new RegExp(this.routePattern,"u"+caseVar).exec(route)))) {
- n = 1;
- for (key in this.references) {
- if (this.references.hasOwnProperty(key)) {
- name = this.references[key];
-
- tr[name]=matches[n];
- n += 1;
- }
- }
- }
- else {
-
- return false;
- }
- }
-
- for (key in this.defaultParams) {
- if (this.defaultParams.hasOwnProperty(key)) {
- value = this.defaultParams[key];
- if(params[key] !== undefined) {
- if(params[key]==value) {
- delete params[key];
- }
- else {
- return false;
- }
- }
- }
- }
-
- for (key in this.params) {
- if (this.params.hasOwnProperty(key)) {
- value = this.params[key];
- if(params[key] === undefined) {
- return false;
- }
- }
- }
-
- if(manager.matchValue && this.matchValue===null || this.matchValue) {
- for (key in this.params) {
- if (this.params.hasOwnProperty(key)) {
- value = this.params[key];
- if(!(new RegExp(value,caseVar)).exec(params[key])) {
- return false;
- }
- }
- }
- }
-
- for (key in this.params) {
- if (this.params.hasOwnProperty(key)) {
- value = this.params[key];
- tr["<" + key + ">"]=php.urlencode(params[key]);
- delete params[key];
- }
- }
- suffix=this.urlSuffix===null ? manager.urlSuffix : this.urlSuffix;
-
- url=php.strtr(this.template,tr);
- if(this.hasHostInfo) {
- hostInfo=Yii.app().getRequest().getHostInfo();
- if(php.stripos(url,hostInfo)===0) {
- url=url.slice(php.strlen(hostInfo));
- }
- }
-
- if(php.empty(params)) {
- return url!=='' ? url+suffix : url;
- }
- if(this.append) {
- url+='/'+manager.createPathInfo(params,'/','/')+suffix;
- }
- else {
- if(url!=='') {
- url+=suffix;
- }
- url+='?'+manager.createPathInfo(params,'=',ampersand);
- }
- return url;
- };
- /**
- * Parases a URL based on this rule.
- * @param {Yii.CUrlManager} manager the URL manager
- * @param {Yii.CHttpRequest} request the request object
- * @param {String} pathInfo path info part of the URL
- * @param {String} rawPathInfo path info that contains the potential URL suffix
- * @returns {Mixed} the route that consists of the controller ID and action ID or false on error
- */
- Yii.CUrlRule.prototype.parseUrl = function (manager, request, pathInfo, rawPathInfo) {
- var caseVar, urlSuffix, matches, name, value, tr, key, i, n;
- if(this.verb!==null && !php.in_array(request.getRequestType(), this.verb, true)) {
- return false;
- }
- if(manager.caseSensitive && this.caseSensitive===null || this.caseSensitive) {
- caseVar='';
- }
- else {
- caseVar='i';
- }
- if(this.urlSuffix!==null) {
- pathInfo=manager.removeUrlSuffix(rawPathInfo,this.urlSuffix);
- }
- // URL suffix required, but not found in the requested URL
- if(manager.useStrictParsing && pathInfo===rawPathInfo) {
- urlSuffix=this.urlSuffix===null ? manager.urlSuffix : this.urlSuffix;
- if(urlSuffix!='' && urlSuffix!=='/') {
- return false;
- }
- }
- if(this.hasHostInfo) {
- pathInfo=request.getHostInfo().toLowerCase()+php.rtrim('/'+pathInfo,'/');
- }
- pathInfo+='/';
- if((matches = new RegExp(this.pattern,caseVar).exec(pathInfo))) {
-
- n = 1;
- tr={};
- for (i in this.references) {
- if (this.references.hasOwnProperty(i)) {
- tr[this.references[i]] = matches[n];
- n += 1;
- }
- }
- for (i in this.params) {
- if (this.params.hasOwnProperty(i)) {
- re = new RegExp(this.params[i]);
- if (re.exec(matches[n])) {
-
- request.params[i] = matches[n];
- n += 1;
- }
- }
- }
- for (i in this.defaultParams) {
- if (this.defaultParams.hasOwnProperty(i)) {
- request.params[i] = this.defaultParams[i];
- }
- }
-
-
- if(pathInfo!==matches[0]) { // there are additional GET params
- manager.parsePathInfo(php.ltrim(pathInfo.slice(php.strlen(matches[0])),'/'));
- }
- if(this.routePattern!==null) {
- return php.strtr(this.route,tr);
- }
- else {
- return this.route;
- }
- }
- else {
- return false;
- }
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CWebApplication extends CApplication by providing functionalities specific to Web requests.
- *
- * CWebApplication manages the controllers in MVC pattern, and provides the following additional
- * core application components:
- * <ul>
- * <li>{@link urlManager}: provides URL parsing and constructing functionality;</li>
- * <li>{@link request}: encapsulates the Web request information;</li>
- * <li>{@link session}: provides the session-related functionalities;</li>
- * <li>{@link assetManager}: manages the publishing of private asset files.</li>
- * <li>{@link user}: represents the user session information.</li>
- * <li>{@link themeManager}: manages themes.</li>
- * <li>{@link authManager}: manages role-based access control (RBAC).</li>
- * <li>{@link clientScript}: manages client scripts (javascripts and CSS).</li>
- * <li>{@link widgetFactory}: creates widgets and supports widget skinning.</li>
- * </ul>
- *
- * User requests are resolved as controller-action pairs and additional parameters.
- * CWebApplication creates the requested controller instance and let it to handle
- * the actual user request. If the user does not specify controller ID, it will
- * assume {@link defaultController} is requested (which defaults to 'site').
- *
- * Controller class files must reside under the directory {@link getControllerPath controllerPath}
- * (defaults to 'protected/controllers'). The file name and the class name must be
- * the same as the controller ID with the first letter in upper case and appended with 'Controller'.
- * For example, the controller 'article' is defined by the class 'ArticleController'
- * which is in the file 'protected/controllers/ArticleController.php'.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CWebApplication.php 3001 2011-02-24 16:42:44Z alexander.makarow $
- * @package system.web
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CApplication
- */
- Yii.CWebApplication = function CWebApplication (config) {
- if (config !== false) {
- this.views = {
- layouts: {
- main: 'application.views.layouts.main'
- }
- };
- this.construct(config);
- }
- };
- Yii.CWebApplication.prototype = new Yii.CApplication(false);
- Yii.CWebApplication.prototype.constructor = Yii.CWebApplication;
- /**
- * @returns {String} the route of the default controller, action or module. Defaults to 'site'.
- */
- Yii.CWebApplication.prototype.defaultController = 'site';
- /**
- * @var {Mixed} the application-wide layout. Defaults to 'main' (relative to {@link getLayoutPath layoutPath}).
- * If this is false, then no layout will be used.
- */
- Yii.CWebApplication.prototype.layout = 'main';
- /**
- * @var {Array} mapping from controller ID to controller configurations.
- * Each name-value pair specifies the configuration for a single controller.
- * A controller configuration can be either a string or an array.
- * If the former, the string should be the class name or
- * {@link YiiBase::getPathOfAlias class path alias} of the controller.
- * If the latter, the array must contain a 'class' element which specifies
- * the controller's class name or {@link YiiBase::getPathOfAlias class path alias}.
- * The rest name-value pairs in the array are used to initialize
- * the corresponding controller properties. For example,
- * <pre>
- * {
- * 'post':{
- * 'class':'path.to.PostController',
- * 'pageTitle':'something new',
- * },
- * 'user':'path.to.UserController',,
- * }
- * </pre>
- *
- * Note, when processing an incoming request, the controller map will first be
- * checked to see if the request can be handled by one of the controllers in the map.
- * If not, a controller will be searched for under the {@link getControllerPath default controller path}.
- */
- Yii.CWebApplication.prototype.controllerMap = [];
- /**
- * @var {Array} the configuration specifying a controller which should handle
- * all user requests. This is mainly used when the application is in maintenance mode
- * and we should use a controller to handle all incoming requests.
- * The configuration specifies the controller route (the first element)
- * and GET parameters (the rest name-value pairs). For example,
- * <pre>
- * {
- * 'offline/notice',
- * 'param1':'value1',
- * 'param2':'value2',
- * }
- * </pre>
- * Defaults to null, meaning catch-all is not effective.
- */
- Yii.CWebApplication.prototype.catchAllRequest = null;
- Yii.CWebApplication.prototype._controllerPath = null;
- Yii.CWebApplication.prototype._viewPath = null;
- Yii.CWebApplication.prototype._systemViewPath = null;
- Yii.CWebApplication.prototype._layoutPath = null;
- Yii.CWebApplication.prototype._controller = null;
- Yii.CWebApplication.prototype._homeUrl = null;
- Yii.CWebApplication.prototype._theme = null;
- /**
- * Processes the current request.
- * It first resolves the request into controller and action,
- * and then creates the controller to perform the action.
- */
- Yii.CWebApplication.prototype.processRequest = function () {
- var route, nameValue, name, value;
- if(Object.prototype.toString.call(this.catchAllRequest) === '[object Array]' && this.catchAllRequest[0] !== undefined) {
- route=this.catchAllRequest[0];
- nameValue = php.array_splice(this.catchAllRequest,1);
- for (name in nameValue) {
- if (nameValue.hasOwnProperty(name)) {
- value = nameValue[name];
- this.getRequest().params[name]=value;
- }
- }
- }
- else {
- route=this.getUrlManager().parseUrl(this.getRequest());
- }
- this.runController(route);
- };
- /**
- * Registers the core application components.
- * This method overrides the parent implementation by registering additional core components.
- * @see setComponents
- */
- Yii.CWebApplication.prototype.registerCoreComponents = function () {
- var components;
- Yii.CApplication.prototype.registerCoreComponents.call(this);
- components={
- 'session':{
- 'class':'CHttpSession'
- },
- 'assetManager':{
- 'class':'CAssetManager'
- },
- 'user':{
- 'class':'CWebUser'
- },
- 'themeManager':{
- 'class':'CThemeManager'
- },
- 'authManager':{
- 'class':'CPhpAuthManager'
- },
- 'clientScript':{
- 'class':'CClientScript'
- },
- 'widgetFactory':{
- 'class':'CWidgetFactory'
- }
- };
- this.setComponents(components);
- };
- /**
- * @returns {IAuthManager} the authorization manager component
- */
- Yii.CWebApplication.prototype.getAuthManager = function () {
- return this.getComponent('authManager');
- };
- /**
- * @returns {Yii.CAssetManager} the asset manager component
- */
- Yii.CWebApplication.prototype.getAssetManager = function () {
- return this.getComponent('assetManager');
- };
- /**
- * @returns {Yii.CHttpSession} the session component
- */
- Yii.CWebApplication.prototype.getSession = function () {
- return this.getComponent('session');
- };
- /**
- * @returns {Yii.CWebUser} the user session information
- */
- Yii.CWebApplication.prototype.getUser = function () {
- return this.getComponent('user');
- };
- /**
- * Returns the view renderer.
- * If this component is registered and enabled, the default
- * view rendering logic defined in {@link CBaseController} will
- * be replaced by this renderer.
- * @returns {IViewRenderer} the view renderer.
- */
- Yii.CWebApplication.prototype.getViewRenderer = function () {
- return this.getComponent('viewRenderer');
- };
- /**
- * Returns the client script manager.
- * @returns {Yii.CClientScript} the client script manager
- */
- Yii.CWebApplication.prototype.getClientScript = function () {
- return this.getComponent('clientScript');
- };
- /**
- * Returns the widget factory.
- * @returns {IWidgetFactory} the widget factory
- * @since 1.1
- */
- Yii.CWebApplication.prototype.getWidgetFactory = function () {
- return this.getComponent('widgetFactory');
- };
- /**
- * @returns {Yii.CThemeManager} the theme manager.
- */
- Yii.CWebApplication.prototype.getThemeManager = function () {
- return this.getComponent('themeManager');
- };
- /**
- * @returns {Yii.CTheme} the theme used currently. Null if no theme is being used.
- */
- Yii.CWebApplication.prototype.getTheme = function () {
- if(typeof(this._theme) === 'string') {
- this._theme=this.getThemeManager().getTheme(this._theme);
- }
- return this._theme;
- };
- /**
- * @param {String} value the theme name
- */
- Yii.CWebApplication.prototype.setTheme = function (value) {
- this._theme=value;
- };
- /**
- * Creates a relative URL based on the given controller and action information.
- * @param {String} route the URL route. This should be in the format of 'ControllerID/ActionID'.
- * @param {Array} params additional GET parameters (name=>value). Both the name and value will be URL-encoded.
- * @param {String} ampersand the token separating name-value pairs in the URL.
- * @returns {String} the constructed URL
- */
- Yii.CWebApplication.prototype.createUrl = function (route, params, ampersand) {
- if (params === undefined) {
- params = [];
- }
- if (ampersand === undefined) {
- ampersand = '&';
- }
- return this.getUrlManager().createUrl(route,params,ampersand);
- };
- /**
- * Creates an absolute URL based on the given controller and action information.
- * @param {String} route the URL route. This should be in the format of 'ControllerID/ActionID'.
- * @param {Array} params additional GET parameters (name=>value). Both the name and value will be URL-encoded.
- * @param {String} schema schema to use (e.g. http, https). If empty, the schema used for the current request will be used.
- * @param {String} ampersand the token separating name-value pairs in the URL.
- * @returns {String} the constructed URL
- */
- Yii.CWebApplication.prototype.createAbsoluteUrl = function (route, params, schema, ampersand) {
- var url;
- if (params === undefined) {
- params = [];
- }
- if (schema === undefined) {
- schema = '';
- }
- if (ampersand === undefined) {
- ampersand = '&';
- }
- url=this.createUrl(route,params,ampersand);
- if(php.strpos(url,'http')===0) {
- return url;
- }
- else {
- return this.getRequest().getHostInfo(schema)+url;
- }
- };
- /**
- * Returns the relative URL for the application.
- * This is a shortcut method to {@link CHttpRequest::getBaseUrl()}.
- * @param {Boolean} absolute whether to return an absolute URL. Defaults to false, meaning returning a relative one.
- * This parameter has been available since 1.0.2.
- * @returns {String} the relative URL for the application
- * @see CHttpRequest::getBaseUrl()
- */
- Yii.CWebApplication.prototype.getBaseUrl = function (absolute) {
- if (absolute === undefined) {
- absolute = false;
- }
- return this.getRequest().getBaseUrl(absolute);
- };
- /**
- * @returns {String} the homepage URL
- */
- Yii.CWebApplication.prototype.getHomeUrl = function () {
- if(this._homeUrl===null) {
- if(this.getUrlManager().showScriptName) {
- return this.getRequest().getScriptUrl();
- }
- else {
- return this.getRequest().getBaseUrl()+'/';
- }
- }
- else {
- return this._homeUrl;
- }
- };
- /**
- * @param {String} value the homepage URL
- */
- Yii.CWebApplication.prototype.setHomeUrl = function (value) {
- this._homeUrl=value;
- };
- /**
- * Creates the controller and performs the specified action.
- * @param {String} route the route of the current request. See {@link createController} for more details.
- * @throws {Yii.CHttpException} if the controller could not be created.
- */
- Yii.CWebApplication.prototype.runController = function (route) {
- var ca, controller, actionID, oldController;
- if((ca=this.createController(route))!==null && ca[0] !== undefined && ca[0] !== false) {
-
- controller = ca[0];
-
- actionID = ca[1];
- // oldController=this._controller;
- this._controller=controller;
- controller.init();
- controller.run(actionID);
- // this._controller=oldController;
- }
- else {
- throw new Yii.CHttpException(404,Yii.t('yii','Unable to resolve the request "{route}".',
- {'{route}':route===''?this.defaultController:route}));
- }
- };
- /**
- * Creates a controller instance based on a route.
- * The route should contain the controller ID and the action ID.
- * It may also contain additional GET variables. All these must be concatenated together with slashes.
- *
- * This method will attempt to create a controller in the following order:
- * <ol>
- * <li>If the first segment is found in {@link controllerMap}, the corresponding
- * controller configuration will be used to create the controller;</li>
- * <li>If the first segment is found to be a module ID, the corresponding module
- * will be used to create the controller;</li>
- * <li>Otherwise, it will search under the {@link controllerPath} to create
- * the corresponding controller. For example, if the route is "admin/user/create",
- * then the controller will be created using the class file "protected/controllers/admin/UserController.php".</li>
- * </ol>
- * @param {String} route the route of the request.
- * @param {Yii.CWebModule} owner the module that the new controller will belong to. Defaults to null, meaning the application
- * instance is the owner.
- * @returns {Array} the controller instance and the action ID. Null if the controller class does not exist or the route is invalid.
- */
- Yii.CWebApplication.prototype.createController = function (route, owner) {
- var caseSensitive, pos, id, basePath = null, module, controllerID, className, classFile;
- if (owner === undefined) {
- owner = null;
- }
- if(owner===null) {
- owner=this;
- }
- if((route=php.trim(route,'/'))==='') {
- route=owner.defaultController;
- }
- caseSensitive=this.getUrlManager().caseSensitive;
- route+='/';
-
- while((pos=php.strpos(route,'/'))!==false) {
- id=route.slice(0, pos);
- if(!/^\w+$/.exec(id)) {
- return null;
- }
- if(!caseSensitive) {
- id=id.toLowerCase();
- }
- route=String(route.slice(pos+1));
- if(basePath === null) {
- // first segment
- if(owner.controllerMap[id] !== undefined) {
- return [
- Yii.createComponent(owner.controllerMap[id],id,owner===this?null:owner),
- this.parseActionParams(route)
- ];
- }
- if((module=owner.getModule(id))!==null && module !== undefined) {
- return this.createController(route,module);
- }
- basePath=owner.getControllerPath();
- controllerID='';
- }
- else {
- controllerID+='/';
- }
- // try and include the file
- className=php.ucfirst(id)+'Controller';
- classFile=basePath+'/'+className+'.js';
-
- return [
- Yii.createComponent(classFile,id,owner===this?null:owner),
- this.parseActionParams(route)
- ];
-
- }
- };
- /**
- * Parses a path info into an action ID and GET variables.
- * @param {String} pathInfo path info
- * @returns {String} action ID
- * @since 1.0.3
- */
- Yii.CWebApplication.prototype.parseActionParams = function (pathInfo) {
- var pos, manager, actionID;
- if((pos=php.strpos(pathInfo,'/'))!==false) {
- manager=this.getUrlManager();
- manager.parsePathInfo(String(pathInfo.slice(pos+1)));
- actionID=pathInfo.slice(0, pos);
- return manager.caseSensitive ? actionID : actionID.toLowerCase();
- }
- else {
- return pathInfo;
- }
- };
- /**
- * @returns {Yii.CController} the currently active controller
- */
- Yii.CWebApplication.prototype.getController = function () {
- return this._controller;
- };
- /**
- * @param {Yii.CController} value the currently active controller
- * @since 1.0.6
- */
- Yii.CWebApplication.prototype.setController = function (value) {
- this._controller=value;
- };
- /**
- * @returns {String} the directory that contains the controller classes. Defaults to 'protected/controllers'.
- */
- Yii.CWebApplication.prototype.getControllerPath = function () {
- if(this._controllerPath!==null) {
- return this._controllerPath;
- }
- else {
- return (this._controllerPath=this.getBasePath()+'/controllers');
- }
- };
- /**
- * @param {String} value the directory that contains the controller classes.
- */
- Yii.CWebApplication.prototype.setControllerPath = function (value) {
- this._controllerPath=value;
- };
- /**
- * @returns {String} the root directory of view files. Defaults to 'protected/views'.
- */
- Yii.CWebApplication.prototype.getViewPath = function () {
- if(this._viewPath!==null) {
- return this._viewPath;
- }
- else {
- return (this._viewPath=this.getBasePath()+'/views');
- }
- };
- /**
- * @param {String} path the root directory of view files.
- */
- Yii.CWebApplication.prototype.setViewPath = function (path) {
- this._viewPath=path;
- };
- /**
- * @returns {String} the root directory of system view files. Defaults to 'protected/views/system'.
- */
- Yii.CWebApplication.prototype.getSystemViewPath = function () {
- if(this._systemViewPath!==null) {
- return this._systemViewPath;
- }
- else {
- return (this._systemViewPath=this.getViewPath()+'/system');
- }
- };
- /**
- * @param {String} path the root directory of system view files.
- */
- Yii.CWebApplication.prototype.setSystemViewPath = function (path) {
- this._systemViewPath=path;
- };
- /**
- * @returns {String} the root directory of layout files. Defaults to 'protected/views/layouts'.
- */
- Yii.CWebApplication.prototype.getLayoutPath = function () {
- if(this._layoutPath!==null) {
- return this._layoutPath;
- }
- else {
- return (this._layoutPath=this.getViewPath()+'/layouts');
- }
- };
- /**
- * @param {String} path the root directory of layout files.
- */
- Yii.CWebApplication.prototype.setLayoutPath = function (path) {
- this._layoutPath=path;
- };
- /**
- * The pre-filter for controller actions.
- * This method is invoked before the currently requested controller action and all its filters
- * are executed. You may override this method with logic that needs to be done
- * before all controller actions.
- * @param {Yii.CController} controller the controller
- * @param {Yii.CAction} action the action
- * @returns {Boolean} whether the action should be executed.
- * @since 1.0.4
- */
- Yii.CWebApplication.prototype.beforeControllerAction = function (controller, action) {
- return true;
- };
- /**
- * The post-filter for controller actions.
- * This method is invoked after the currently requested controller action and all its filters
- * are executed. You may override this method with logic that needs to be done
- * after all controller actions.
- * @param {Yii.CController} controller the controller
- * @param {Yii.CAction} action the action
- * @since 1.0.4
- */
- Yii.CWebApplication.prototype.afterControllerAction = function (controller, action) {
- };
- /**
- * Searches for a module by its ID.
- * This method is used internally. Do not call this method.
- * @param {String} id module ID
- * @returns {Yii.CWebModule} the module that has the specified ID. Null if no module is found.
- * @since 1.0.3
- */
- Yii.CWebApplication.prototype.findModule = function (id) {
- var controller, module, m;
- if((controller=this.getController())!==null && (module=controller.getModule())!==null) {
- do
- {
- if((m=module.getModule(id))!==null) {
- return m;
- }
- } while((module=module.getParentModule())!==null);
- }
- if((m=this.getModule(id))!==null) {
- return m;
- }
- };
- /**
- * Initializes the application.
- * This method overrides the parent implementation by preloading the 'request' component.
- */
- Yii.CWebApplication.prototype.init = function () {
- Yii.CApplication.prototype.init.call(this);
- // preload 'request' so that it has chance to respond to onBeginRequest event.
- this.getRequest();
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CWidgetFactory creates new widgets to be used in views.
- *
- * CWidgetFactory is used as the default "widgetFactory" application component.
- *
- * When calling {@link CBaseController::createWidget}, {@link CBaseController::widget}
- * or {@link CBaseController::beginWidget}, if the "widgetFactory" component is installed,
- * it will be used to create the requested widget. To install the "widgetFactory" component,
- * we should have the following application configuration:
- * <pre>
- * return {
- * 'components':{
- * 'widgetFactory':{
- * 'class':'CWidgetFactory',
- * },
- * ),
- * }
- * </pre>
- *
- * CWidgetFactory implements the "skin" feature, which allows a new widget to be created
- * and initialized with a set of predefined property values (called skin).
- *
- * When CWidgetFactory is used to create a new widget, it will first instantiate the
- * widget instance. It then checks if there is a skin available for this widget
- * according to the widget class name and the widget {@link CWidget::skin} property.
- * If a skin is found, it will be merged with the initial properties passed via
- * {@link createWidget}. Then the merged initial properties will be used to initialize
- * the newly created widget instance.
- *
- * As aforementioned, a skin is a set of initial property values for a widget.
- * It is thus represented as an associative array of name-value pairs.
- * Skins are stored in PHP scripts like other configurations. Each script file stores the skins
- * for a particular widget type and is named as the wiget class name (e.g. CLinkPager.php).
- * Each widget type may have one or several skins, identified by the skin name set via
- * {@link CWidget::skin} property. If the {@link CWidget::skin} property is not set for a given
- * widget, it means the default skin would be used. The following shows the possible skins for
- * the {@link CLinkPager} widget:
- * <pre>
- * return {
- * 'default':{
- * 'nextPageLabel':'>>',
- * 'prevPageLabel':'<<',
- * },
- * 'short':{
- * 'header':'',
- * 'maxButtonCount':5,
- * },
- * };
- * </pre>
- * In the above, there are two skins. The first one is the default skin which is indexed by the string "default".
- * Note that {@link CWidget::skin} defaults to "default". Therefore, this is the skin that will be applied
- * if we do not explicitly specify the {@link CWidget::skin} property.
- * The second one is named as the "short" skin which will be used only when we set {@link CWidget::skin}
- * to be "short".
- *
- * By default, CWidgetFactory looks for the skin of a widget under the "skins" directory
- * of the current application's {@link CWebApplication::viewPath} (e.g. protected/views/skins).
- * If a theme is being used, it will look for the skin under the "skins" directory of
- * the theme's {@link CTheme::viewPath} (as well as the aforementioned skin directory).
- * In case the specified skin is not found, a widget will still be created
- * normally without causing any error.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CWidgetFactory.php 2799 2011-01-01 19:31:13Z qiang.xue $
- * @package system.web
- * @since 1.1
- * @author Charles Pick
- * @class
- * @extends Yii.CApplicationComponent
- */
- Yii.CWidgetFactory = function CWidgetFactory () {
- };
- Yii.CWidgetFactory.prototype = new Yii.CApplicationComponent();
- Yii.CWidgetFactory.prototype.constructor = Yii.CWidgetFactory;
- /**
- * @var {Object} widget initial property values. Each array key-value pair
- * represents the initial property values for a single widget class, with
- * the array key being the widget class name, and array value being the initial
- * property value array. For example,
- * <pre>
- * {
- * 'CLinkPager':{
- * 'maxButtonCount':5,
- * 'cssFile':false,
- * ),
- * 'CJuiDatePicker':{
- * 'language':'ru',
- * },
- * }
- * </pre>
- *
- * Note that the initial values specified here may be overridden by
- * the values given in {@link CBaseController::createWidget} calls.
- * They may also be overridden by widget skins, if {@link enableSkin} is true.
- * @since 1.1.3
- */
- Yii.CWidgetFactory.prototype.widgets = {};
- /**
- * Initializes the application component.
- * This method overrides the parent implementation by resolving the skin path.
- */
- Yii.CWidgetFactory.prototype.init = function () {
- Yii.CApplicationComponent.prototype.init.call(this);
-
- };
- /**
- * Creates a new widget based on the given class name and initial properties.
- * @param {Yii.CBaseController} owner the owner of the new widget
- * @param {String} className the class name of the widget. This can also be a path alias (e.g. system.web.widgets.COutputCache)
- * @param {Array} properties the initial property values (name=>value) of the widget.
- * @returns {Yii.CWidget} the newly created widget whose properties have been initialized with the given values.
- */
- Yii.CWidgetFactory.prototype.createWidget = function (owner, className, properties) {
- var widget, skinName, skin, name, value;
- if (properties === undefined) {
- properties = [];
- }
- className=Yii.imports(className,true);
- widget=new Yii[className](owner);
-
- if(this.widgets[className] !== undefined) {
- properties=properties===[] ? this.widgets[className] : Yii.CMap.prototype.mergeArray(this.widgets[className],properties);
- }
-
- for (name in properties) {
- if (properties.hasOwnProperty(name)) {
- value = properties[name];
- widget[name]=value;
- }
- }
- return widget;
- };
- /*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CAction is the base class for all controller action classes.
- *
- * CAction provides a way to divide a complex controller into
- * smaller actions in separate class files.
- *
- * Derived classes must implement {@link run()} which is invoked by
- * controller when the action is requested.
- *
- * An action instance can access its controller via {@link getController controller} property.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CAction.php 3058 2011-03-13 04:20:12Z qiang.xue $
- * @package system.web.actions
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CComponent
- */
- Yii.CAction = function CAction(controller, id) {
- if (controller !== false) {
- this.construct(controller, id);
- }
- };
- Yii.CAction.prototype = new Yii.CComponent();
- Yii.CAction.prototype.constructor = Yii.CAction;
- Yii.CAction.prototype._id = null;
- Yii.CAction.prototype._controller = null;
- /**
- * Constructor.
- * @param {Yii.CController} controller the controller who owns this action.
- * @param {String} id id of the action.
- */
- Yii.CAction.prototype.construct = function (controller, id) {
- this._controller=controller;
- this._id=id;
- };
- /**
- * @returns {Yii.CController} the controller who owns this action.
- */
- Yii.CAction.prototype.getController = function () {
- return this._controller;
- };
- /**
- * @returns {String} id of this action
- */
- Yii.CAction.prototype.getId = function () {
- return this._id;
- };
- /**
- * Runs the action with the supplied request parameters.
- * This method is internally called by {@link CController::runAction()}.
- * @param {Array} params the request parameters (name=>value)
- * @returns {Boolean} whether the request parameters are valid
- * @since 1.1.7
- */
- Yii.CAction.prototype.runWithParams = function (params) {
- var methodParams = [], matches;
- matches = /function(.*)\((.*)\)/.exec(this.run);
- if (matches) {
- methodParams = matches[2].split(/[\s,]+/);
- }
- if(methodParams.length >0) {
- return this.runWithParamsInternal(this, "run", params);
- }
- else {
- return this.run();
- }
- };
- /**
- * Executes a method of an object with the supplied named parameters.
- * This method is internally used.
- * @param {Mixed} object the object whose method is to be executed
- * @param {String} method the name of the method
- * @param {Array} params the named parameters
- * @returns {Boolean} whether the named parameters are valid
- * @since 1.1.7
- */
- Yii.CAction.prototype.runWithParamsInternal = function (object, method, params) {
- var ps, paramList, name, param, i, limit;
- ps=[];
- paramList = /function(.*)\((.*)\)/.exec(object[method]).pop();
- if (paramList !== '') {
- paramList = paramList.split(/[\s,]+/);
- }
- else {
- paramList = [];
- }
- limit = paramList.length;
- for (i = 0; i < limit; i++) {
- name = paramList[i];
- if(params !== undefined && params[name] !== undefined) {
- ps.push(params[name]);
- }
- }
- object[method].apply(object,ps);
- return true;
- }/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CInlineAction represents an action that is defined as a controller method.
- *
- * The method name is like 'actionXYZ' where 'XYZ' stands for the action name.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CInlineAction.php 3137 2011-03-28 11:08:06Z mdomba $
- * @package system.web.actions
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CAction
- */
- Yii.CInlineAction = function CInlineAction(controller, id) {
- if (controller !== false) {
- this.construct(controller, id);
- }
- };
- Yii.CInlineAction.prototype = new Yii.CAction(false);
- Yii.CInlineAction.prototype.constructor = Yii.CInlineAction;
- /**
- * Runs the action.
- * The action method defined in the controller is invoked.
- * This method is required by {@link CAction}.
- */
- Yii.CInlineAction.prototype.run = function () {
- var method;
- method='action'+php.ucfirst(this.getId());
- this.getController()[method]();
- };
- /**
- * Runs the action with the supplied request parameters.
- * This method is internally called by {@link CController::runAction()}.
- * @param {Array} params the request parameters (name=>value)
- * @returns {Boolean} whether the request parameters are valid
- * @since 1.1.7
- */
- Yii.CInlineAction.prototype.runWithParams = function (params) {
- var methodName, controller, method, paramList;
- methodName='action'+this.getId();
- controller=this.getController();
- paramList = (/function(.*)\((.*)\)/.exec(controller[methodName])).pop();
-
- if(paramList.length > 0) {
- return this.runWithParamsInternal(controller, methodName, params);
- }
- else {
- return controller[methodName]();
- }
- }/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CViewAction represents an action that displays a view according to a user-specified parameter.
- *
- * By default, the view being displayed is specified via the <code>view</code> GET parameter.
- * The name of the GET parameter can be customized via {@link viewParam}.
- * If the user doesn't provide the GET parameter, the default view specified by {@link defaultView}
- * will be displayed.
- *
- * Users specify a view in the format of <code>path.to.view</code>, which translates to the view name
- * <code>BasePath/path/to/view</code> where <code>BasePath</code> is given by {@link basePath}.
- *
- * Note, the user specified view can only contain word characters, dots and dashes and
- * the first letter must be a word letter.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CViewAction.php 2799 2011-01-01 19:31:13Z qiang.xue $
- * @package system.web.actions
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CAction
- */
- Yii.CViewAction = function CViewAction (controller, id) {
- if (controller !== false) {
- this.construct(controller, id);
- }
- };
- Yii.CViewAction.prototype = new Yii.CAction(false);
- Yii.CViewAction.prototype.constructor = Yii.CViewAction;
- /**
- * @var {String} the name of the GET parameter that contains the requested view name. Defaults to 'view'.
- */
- Yii.CViewAction.prototype.viewParam = 'view';
- /**
- * @var {String} the name of the default view when {@link viewParam} GET parameter is not provided by user. Defaults to 'index'.
- * This should be in the format of 'path.to.view', similar to that given in
- * the GET parameter.
- * @see basePath
- */
- Yii.CViewAction.prototype.defaultView = 'index';
- /**
- * @var {String} the name of the view to be rendered. This property will be set
- * once the user requested view is resolved.
- */
- Yii.CViewAction.prototype.view = null;
- /**
- * @var {String} the base path for the views. Defaults to 'pages'.
- * The base path will be prefixed to any user-specified page view.
- * For example, if a user requests for <code>tutorial.chap1</code>, the corresponding view name will
- * be <code>pages/tutorial/chap1</code>, assuming the base path is <code>pages</code>.
- * The actual view file is determined by {@link CController::getViewFile}.
- * @see CController::getViewFile
- */
- Yii.CViewAction.prototype.basePath = 'pages';
- /**
- * @var {Mixed} the name of the layout to be applied to the views.
- * This will be assigned to {@link CController::layout} before the view is rendered.
- * Defaults to null, meaning the controller's layout will be used.
- * If false, no layout will be applied.
- */
- Yii.CViewAction.prototype.layout = null;
- /**
- * @var {Boolean} whether the view should be rendered as PHP script or static text. Defaults to false.
- */
- Yii.CViewAction.prototype.renderAsText = false;
- Yii.CViewAction.prototype._viewPath = null;
- /**
- * Returns the name of the view requested by the user.
- * If the user doesn't specify any view, the {@link defaultView} will be returned.
- * @returns {String} the name of the view requested by the user.
- * This is in the format of 'path.to.view'.
- */
- Yii.CViewAction.prototype.getRequestedView = function () {
- if(this._viewPath===null) {
- if(!php.empty(Yii.app().getRequest().params[this.viewParam])) {
- this._viewPath=Yii.app().getRequest().params[this.viewParam];
- }
- else {
- this._viewPath=this.defaultView;
- }
- }
- return this._viewPath;
- };
- /**
- * Resolves the user-specified view into a valid view name.
- * @param {String} viewPath user-specified view in the format of 'path.to.view'.
- * @returns {String} fully resolved view in the format of 'path/to/view'.
- * @throw CHttpException if the user-specified view is invalid
- */
- Yii.CViewAction.prototype.resolveView = function (viewPath) {
- var view;
- // start with a word char and have word chars, dots and dashes only
- if(/^\w[\w\.\-]*$/.exec(viewPath)) {
- view=php.strtr(viewPath,'.','/');
- if(!php.empty(this.basePath)) {
- view=this.basePath+'/'+view;
- }
- if(this.getController().getViewFile(view)!==false) {
- this.view=view;
- return;
- }
- }
- throw new Yii.CHttpException(404,Yii.t('yii','The requested view "{name}" was not found.',
- {'{name}':viewPath}));
- };
- /**
- * Runs the action.
- * This method displays the view requested by the user.
- * @throws {Yii.CHttpException} if the view is invalid
- */
- Yii.CViewAction.prototype.run = function () {
- var controller, layout, event, text;
- this.resolveView(this.getRequestedView());
- controller=this.getController();
-
- if(this.layout!==null) {
- layout=controller.layout;
- controller.layout=this.layout;
- }
-
- this.onBeforeRender(event=new Yii.CEvent(this));
- if(!event.handled) {
- if(this.renderAsText) {
- text=file_get_contents(controller.getViewFile(this.view));
- controller.renderText(text);
- }
- else {
-
- controller.render(this.view, {}, function(html) {
- jQuery("body").html(html);
- });
- }
- this.onAfterRender(new Yii.CEvent(this));
- }
- if(this.layout!==null) {
- controller.layout=layout;
- }
- };
- /**
- * Raised right before the action invokes the render method.
- * Event handlers can set the {@link CEvent::handled} property
- * to be true to stop further view rendering.
- * @param {Yii.CEvent} event event parameter
- */
- Yii.CViewAction.prototype.onBeforeRender = function (event) {
- this.raiseEvent('onBeforeRender',event);
- };
- /**
- * Raised right after the action invokes the render method.
- * @param {Yii.CEvent} event event parameter
- */
- Yii.CViewAction.prototype.onAfterRender = function (event) {
- this.raiseEvent('onAfterRender',event);
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CAccessControlFilter performs authorization checks for the specified actions.
- *
- * By enabling this filter, controller actions can be checked for access permissions.
- * When the user is not denied by one of the security rules or allowed by a rule explicitly,
- * he will be able to access the action.
- *
- * For maximum security consider adding
- * <pre>['deny']</pre>
- * as a last rule in a list so all actions will be denied by default.
- *
- * To specify the access rules, set the {@link setRules rules} property, which should
- * be an array of the rules. Each rule is specified as an array of the following structure:
- * <pre>
- * {
- * 'allow', // or 'deny'
- * // optional, list of action IDs (case insensitive) that this rule applies to
- * 'actions':{'edit', 'delete'},
- * // optional, list of controller IDs (case insensitive) that this rule applies to
- * // This option is available since version 1.0.3.
- * 'controllers':{'post', 'admin/user'},
- * // optional, list of usernames (case insensitive) that this rule applies to
- * // Use * to represent all users, ? guest users, and @ authenticated users
- * 'users':{'thomas', 'kevin'},
- * // optional, list of roles (case sensitive!) that this rule applies to.
- * 'roles':{'admin', 'editor'},
- * // optional, list of IP address/patterns that this rule applies to
- * // e.g. 127.0.0.1, 127.0.0.*
- * 'ips':{'127.0.0.1'},
- * // optional, list of request types (case insensitive) that this rule applies to
- * 'verbs':{'GET', 'POST'},
- * // optional, a PHP expression whose value indicates whether this rule applies
- * // This option is available since version 1.0.3.
- * 'expression':'!$user->isGuest && $user->level==2',
- * // optional, the customized error message to be displayed
- * // This option is available since version 1.1.1.
- * 'message':'Access Denied.',
- * }
- * </pre>
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CAccessControlFilter.php 3001 2011-02-24 16:42:44Z alexander.makarow $
- * @package system.web.auth
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CFilter
- */
- Yii.CAccessControlFilter = function CAccessControlFilter () {
- };
- Yii.CAccessControlFilter.prototype = new Yii.CFilter();
- Yii.CAccessControlFilter.prototype.constructor = Yii.CAccessControlFilter;
- /**
- * @var {String} the error message to be displayed when authorization fails.
- * This property can be overridden by individual access rule via {@link CAccessRule::message}.
- * If this property is not set, a default error message will be displayed.
- * @since 1.1.1
- */
- Yii.CAccessControlFilter.prototype.message = null;
- Yii.CAccessControlFilter.prototype._rules = [];
- /**
- * @returns {Array} list of access rules.
- */
- Yii.CAccessControlFilter.prototype.getRules = function () {
- return this._rules;
- };
- /**
- * @param {Array} rules list of access rules.
- */
- Yii.CAccessControlFilter.prototype.setRules = function (rules) {
- var i, rule, r, nameValue, name, value;
- for (i in rules) {
- if (rules.hasOwnProperty(i)) {
- rule = rules[i];
- if(Object.prototype.toString.call(rule) === '[object Array]' && rule[0] !== undefined)
- {
- r=new Yii.CAccessRule();
- r.allow=rule[0]==='allow';
- nameValue = php.array_slice(rule,1);
- for (name in nameValue) {
- if (nameValue.hasOwnProperty(name)) {
- value = nameValue[name];
- if(name==='expression' || name==='roles' || name==='message') {
- r.name=value;
- }
- else {
- r.name=php.array_map('strtolower',value);
- }
- }
- }
- this._rules.push(r);
- }
- }
- }
- };
- /**
- * Performs the pre-action filtering.
- * @param {Yii.CFilterChain} filterChain the filter chain that the filter is on.
- * @returns {Boolean} whether the filtering process should continue and the action
- * should be executed.
- */
- Yii.CAccessControlFilter.prototype.preFilter = function (filterChain) {
- var app, request, user, verb, ip, i, ruleList, allow, rule;
- app=Yii.app();
- request=app.getRequest();
- user=app.getUser();
- verb=request.getRequestType();
- ip=request.getUserHostAddress();
- ruleList = this.getRules();
- for (i in ruleList) {
- if (ruleList.hasOwnProperty(i)) {
- rule = ruleList[i];
- if((allow=rule.isUserAllowed(user,filterChain.controller,filterChain.action,ip,verb))>0) { // allowed
- break;
- }
- else if(allow<0) {
- // denied
- this.accessDenied(user,this.resolveErrorMessage(rule));
- return false;
- }
- }
- }
- return true;
- };
- /**
- * Resolves the error message to be displayed.
- * This method will check {@link message} and {@link CAccessRule::message} to see
- * what error message should be displayed.
- * @param {Yii.CAccessRule} rule the access rule
- * @returns {String} the error message
- * @since 1.1.1
- */
- Yii.CAccessControlFilter.prototype.resolveErrorMessage = function (rule) {
- if(rule.message!==null) {
- return rule.message;
- }
- else if(this.message!==null) {
- return this.message;
- }
- else {
- return Yii.t('yii','You are not authorized to perform this action.');
- }
- };
- /**
- * Denies the access of the user.
- * This method is invoked when access check fails.
- * @param {IWebUser} user the current user
- * @param {String} message the error message to be displayed
- * @since 1.0.5
- */
- Yii.CAccessControlFilter.prototype.accessDenied = function (user, message) {
- if(user.getIsGuest()) {
- user.loginRequired();
- }
- else {
- throw new Yii.CHttpException(403,message);
- }
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CAccessRule represents an access rule that is managed by {@link CAccessControlFilter}.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CAccessControlFilter.php 3001 2011-02-24 16:42:44Z alexander.makarow $
- * @package system.web.auth
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CComponent
- */
- Yii.CAccessRule = function CAccessRule () {
- };
- Yii.CAccessRule.prototype = new Yii.CComponent();
- Yii.CAccessRule.prototype.constructor = Yii.CAccessRule;
- /**
- * @var {Boolean} whether this is an 'allow' rule or 'deny' rule.
- */
- Yii.CAccessRule.prototype.allow = null;
- /**
- * @var {Array} list of action IDs that this rule applies to. The comparison is case-insensitive.
- */
- Yii.CAccessRule.prototype.actions = null;
- /**
- * @var {Array} list of controler IDs that this rule applies to. The comparison is case-insensitive.
- * @since 1.0.4
- */
- Yii.CAccessRule.prototype.controllers = null;
- /**
- * @var {Array} list of user names that this rule applies to. The comparison is case-insensitive.
- */
- Yii.CAccessRule.prototype.users = null;
- /**
- * @var {Array} list of roles this rule applies to. For each role, the current user's
- * {@link CWebUser::checkAccess} method will be invoked. If one of the invocations
- * returns true, the rule will be applied.
- * Note, you should mainly use roles in an "allow" rule because by definition,
- * a role represents a permission collection.
- * @see CAuthManager
- */
- Yii.CAccessRule.prototype.roles = null;
- /**
- * @var {Array} IP patterns.
- */
- Yii.CAccessRule.prototype.ips = null;
- /**
- * @var {Array} list of request types (e.g. GET, POST) that this rule applies to.
- */
- Yii.CAccessRule.prototype.verbs = null;
- /**
- * @var {String} a PHP expression whose value indicates whether this rule should be applied.
- * In this expression, you can use <code>$user</code> which refers to <code>Yii::app()->user</code>.
- * Starting from version 1.0.11, the expression can also be a valid PHP callback,
- * including class method name (array(ClassName/Object, MethodName)),
- * or anonymous function (PHP 5.3.0+). The function/method signature should be as follows:
- * <pre>
- * function foo(user, rule) { +++ }
- * </pre>
- * where $user is the current application user object and $rule is this access rule.
- * @since 1.0.3
- */
- Yii.CAccessRule.prototype.expression = null;
- /**
- * @var {String} the error message to be displayed when authorization is denied by this rule.
- * If not set, a default error message will be displayed.
- * @since 1.1.1
- */
- Yii.CAccessRule.prototype.message = null;
- /**
- * Checks whether the Web user is allowed to perform the specified action.
- * @param {Yii.CWebUser} user the user object
- * @param {Yii.CController} controller the controller currently being executed
- * @param {Yii.CAction} action the action to be performed
- * @param {String} ip the request IP address
- * @param {String} verb the request verb (GET, POST, etc.)
- * @returns {Integer} 1 if the user is allowed, -1 if the user is denied, 0 if the rule does not apply to the user
- */
- Yii.CAccessRule.prototype.isUserAllowed = function (user, controller, action, ip, verb) {
- if(this.isActionMatched(action)
- && this.isUserMatched(user)
- && this.isRoleMatched(user)
- && this.isIpMatched(ip)
- && this.isVerbMatched(verb)
- && this.isControllerMatched(controller)
- && this.isExpressionMatched(user)) {
- return this.allow ? 1 : -1;
- }
- else {
- return 0;
- }
- };
- /**
- * @param {Yii.CAction} action the action
- * @returns {Boolean} whether the rule applies to the action
- */
- Yii.CAccessRule.prototype.isActionMatched = function (action) {
- return php.empty(this.actions) || php.in_array(action.getId().toLowerCase(),this.actions);
- };
- /**
- * @param {Yii.CAction} controller the action
- * @returns {Boolean} whether the rule applies to the action
- */
- Yii.CAccessRule.prototype.isControllerMatched = function (controller) {
- return php.empty(this.controllers) || php.in_array(controller.getId().toLowerCase(),this.controllers);
- };
- /**
- * @param {IWebUser} user the user
- * @returns {Boolean} whether the rule applies to the user
- */
- Yii.CAccessRule.prototype.isUserMatched = function (user) {
- var i, u;
- if(php.empty(this.users)) {
- return true;
- }
- for (i in this.users)
- {
- if (this.users.hasOwnProperty(i)) {
- u = this.users[i];
- if(u==='*') {
- return true;
- }
- else if(u==='?' && user.getIsGuest()) {
- return true;
- }
- else if(u==='@' && !user.getIsGuest()) {
- return true;
- }
- else if(!php.strcasecmp(u,user.getName())) {
- return true;
- }
- }
- }
- return false;
- };
- /**
- * @param {IWebUser} user the user object
- * @returns {Boolean} whether the rule applies to the role
- */
- Yii.CAccessRule.prototype.isRoleMatched = function (user) {
- var i, role;
- if(php.empty(this.roles)) {
- return true;
- }
- for (i in this.roles)
- {
- if (this.roles.hasOwnProperty(i)) {
- role = this.roles[i];
- if(user.checkAccess(role)) {
- return true;
- }
- }
- }
- return false;
- };
- /**
- * @param {String} ip the IP address
- * @returns {Boolean} whether the rule applies to the IP address
- */
- Yii.CAccessRule.prototype.isIpMatched = function (ip) {
- var i, rule, pos;
- if(php.empty(this.ips)) {
- return true;
- }
- for (i in this.ips)
- {
- if (this.ips.hasOwnProperty(i)) {
- rule = this.ips[i];
- if(rule==='*' || rule===ip || ((pos=php.strpos(rule,'*'))!==false && !php.strncmp(ip,rule,pos))) {
- return true;
- }
- }
- }
- return false;
- };
- /**
- * @param {String} verb the request method
- * @returns {Boolean} whether the rule applies to the request
- */
- Yii.CAccessRule.prototype.isVerbMatched = function (verb) {
- return php.empty(this.verbs) || php.in_array(verb.toLowerCase(),this.verbs);
- };
- /**
- * @param {IWebUser} user the user
- * @returns {Boolean} the expression value. True if the expression is not specified.
- * @since 1.0.3
- */
- Yii.CAccessRule.prototype.isExpressionMatched = function (user) {
- if(this.expression===null) {
- return true;
- }
- else {
- return this.evaluateExpression(this.expression, {'user':user});
- }
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CBaseUserIdentity is a base class implementing {@link IUserIdentity}.
- *
- * CBaseUserIdentity implements the scheme for representing identity
- * information that needs to be persisted. It also provides the way
- * to represent the authentication errors.
- *
- * Derived classes should implement {@link IUserIdentity::authenticate}
- * and {@link IUserIdentity::getId} that are required by the {@link IUserIdentity}
- * interface.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CBaseUserIdentity.php 3001 2011-02-24 16:42:44Z alexander.makarow $
- * @package system.web.auth
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CComponent
- */
- Yii.CBaseUserIdentity = function CBaseUserIdentity () {
- };
- Yii.CBaseUserIdentity.prototype = new Yii.CComponent();
- Yii.CBaseUserIdentity.prototype.constructor = Yii.CBaseUserIdentity;
- /**
- * @const
- */
- Yii.CBaseUserIdentity.ERROR_NONE = 0;
- /**
- * @const
- */
- Yii.CBaseUserIdentity.ERROR_USERNAME_INVALID = 1;
- /**
- * @const
- */
- Yii.CBaseUserIdentity.ERROR_PASSWORD_INVALID = 2;
- /**
- * @const
- */
- Yii.CBaseUserIdentity.ERROR_UNKNOWN_IDENTITY = 100;
- /**
- * @var {Integer} the authentication error code. If there is an error, the error code will be non-zero.
- * Defaults to 100, meaning unknown identity. Calling {@link authenticate} will change this value.
- */
- Yii.CBaseUserIdentity.prototype.errorCode = 100;
- /**
- * @var {String} the authentication error message. Defaults to empty.
- */
- Yii.CBaseUserIdentity.prototype.errorMessage = '';
- Yii.CBaseUserIdentity.prototype._state = [];
- /**
- * Returns a value that uniquely represents the identity.
- * @returns {Mixed} a value that uniquely represents the identity (e.g. primary key value).
- * The default implementation simply returns {@link name}.
- */
- Yii.CBaseUserIdentity.prototype.getId = function () {
- return this.getName();
- };
- /**
- * Returns the display name for the identity (e.g. username).
- * @returns {String} the display name for the identity.
- * The default implementation simply returns empty string.
- */
- Yii.CBaseUserIdentity.prototype.getName = function () {
- return '';
- };
- /**
- * Returns the identity states that should be persisted.
- * This method is required by {@link IUserIdentity}.
- * @returns {Array} the identity states that should be persisted.
- */
- Yii.CBaseUserIdentity.prototype.getPersistentStates = function () {
- return this._state;
- };
- /**
- * Sets an array of presistent states.
- *
- * @param {Array} states the identity states that should be persisted.
- */
- Yii.CBaseUserIdentity.prototype.setPersistentStates = function (states) {
- this._state = states;
- };
- /**
- * Returns a value indicating whether the identity is authenticated.
- * This method is required by {@link IUserIdentity}.
- * @returns {Whether} the authentication is successful.
- */
- Yii.CBaseUserIdentity.prototype.getIsAuthenticated = function () {
- return this.errorCode==this.ERROR_NONE;
- };
- /**
- * Gets the persisted state by the specified name.
- * @param {String} name the name of the state
- * @param {Mixed} defaultValue the default value to be returned if the named state does not exist
- * @returns {Mixed} the value of the named state
- */
- Yii.CBaseUserIdentity.prototype.getState = function (name, defaultValue) {
- if (defaultValue === undefined) {
- defaultValue = null;
- }
- return this._state[name] !== undefined?this._state[name]:defaultValue;
- };
- /**
- * Sets the named state with a given value.
- * @param {String} name the name of the state
- * @param {Mixed} value the value of the named state
- */
- Yii.CBaseUserIdentity.prototype.setState = function (name, value) {
- this._state[name]=value;
- };
- /**
- * Removes the specified state.
- * @param {String} name the name of the state
- * @since 1.0.8
- */
- Yii.CBaseUserIdentity.prototype.clearState = function (name) {
- delete this._state[name];
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CUserIdentity is a base class for representing identities that are authenticated based on a username and a password.
- *
- * Derived classes should implement {@link authenticate} with the actual
- * authentication scheme (e.g. checking username and password against a DB table).
- *
- * By default, CUserIdentity assumes the {@link username} is a unique identifier
- * and thus use it as the {@link id ID} of the identity.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CUserIdentity.php 2799 2011-01-01 19:31:13Z qiang.xue $
- * @package system.web.auth
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CBaseUserIdentity
- */
- Yii.CUserIdentity = function CUserIdentity (username, password) {
- if (username !== false) {
- this.construct(username, password);
- }
- };
- Yii.CUserIdentity.prototype = new Yii.CBaseUserIdentity();
- Yii.CUserIdentity.prototype.constructor = Yii.CUserIdentity;
- /**
- * @var {String} username
- */
- Yii.CUserIdentity.prototype.username = null;
- /**
- * @var {String} password
- */
- Yii.CUserIdentity.prototype.password = null;
- /**
- * Constructor.
- * @param {String} username username
- * @param {String} password password
- */
- Yii.CUserIdentity.prototype.construct = function (username, password) {
- this.username=username;
- this.password=password;
- };
- /**
- * Authenticates a user based on {@link username} and {@link password}.
- * Derived classes should override this method, or an exception will be thrown.
- * This method is required by {@link IUserIdentity}.
- * @returns {Boolean} whether authentication succeeds.
- */
- Yii.CUserIdentity.prototype.authenticate = function () {
- throw new Yii.CException(Yii.t('yii','{class}::authenticate() must be implemented.',{'{class}':this.getClassName()}));
- };
- /**
- * Returns the unique identifier for the identity.
- * The default implementation simply returns {@link username}.
- * This method is required by {@link IUserIdentity}.
- * @returns {String} the unique identifier for the identity.
- */
- Yii.CUserIdentity.prototype.getId = function () {
- return this.username;
- };
- /**
- * Returns the display name for the identity.
- * The default implementation simply returns {@link username}.
- * This method is required by {@link IUserIdentity}.
- * @returns {String} the display name for the identity.
- */
- Yii.CUserIdentity.prototype.getName = function () {
- return this.username;
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CWebUser represents the persistent state for a Web application user.
- *
- * CWebUser is used as an application component whose ID is 'user'.
- * Therefore, at any place one can access the user state via
- * <code>Yii::app()->user</code>.
- *
- * CWebUser should be used together with an {@link IUserIdentity identity}
- * which implements the actual authentication algorithm.
- *
- * A typical authentication process using CWebUser is as follows:
- * <ol>
- * <li>The user provides information needed for authentication.</li>
- * <li>An {@link IUserIdentity identity instance} is created with the user-provided information.</li>
- * <li>Call {@link IUserIdentity::authenticate} to check if the identity is valid.</li>
- * <li>If valid, call {@link CWebUser::login} to login the user, and
- * Redirect the user browser to {@link returnUrl}.</li>
- * <li>If not valid, retrieve the error code or message from the identity
- * instance and display it.</li>
- * </ol>
- *
- * The property {@link id} and {@link name} are both identifiers
- * for the user. The former is mainly used internally (e.g. primary key), while
- * the latter is for display purpose (e.g. username). The {@link id} property
- * is a unique identifier for a user that is persistent
- * during the whole user session. It can be a username, or something else,
- * depending on the implementation of the {@link IUserIdentity identity class}.
- *
- * Both {@link id} and {@link name} are persistent during the user session.
- * Besides, an identity may have additional persistent data which can
- * be accessed by calling {@link getState}.
- * Note, when {@link allowAutoLogin cookie-based authentication} is enabled,
- * all these persistent data will be stored in cookie. Therefore, do not
- * store password or other sensitive data in the persistent storage. Instead,
- * you should store them directly in session on the server side if needed.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CWebUser.php 3167 2011-04-07 04:25:27Z qiang.xue $
- * @package system.web.auth
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CApplicationComponent
- */
- Yii.CWebUser = function CWebUser() {
- };
- Yii.CWebUser.prototype = new Yii.CApplicationComponent();
- Yii.CWebUser.prototype.constructor = Yii.CWebUser;
- /**
- * @const
- */
- Yii.CWebUser.prototype.FLASH_KEY_PREFIX = 'Yii.CWebUser.flash.';
- /**
- * @const
- */
- Yii.CWebUser.prototype.FLASH_COUNTERS ='Yii.CWebUser.flashcounters';
- /**
- * @const
- */
- Yii.CWebUser.prototype.STATES_VAR = '__states';
- /**
- * @const
- */
- Yii.CWebUser.prototype.AUTH_TIMEOUT_VAR = '__timeout';
- /**
- * @var {Boolean} whether to enable cookie-based login. Defaults to false.
- */
- Yii.CWebUser.prototype.allowAutoLogin = false;
- /**
- * @var {String} the name for a guest user. Defaults to 'Guest'.
- * This is used by {@link getName} when the current user is a guest (not authenticated).
- */
- Yii.CWebUser.prototype.guestName = 'Guest';
- /**
- * @var {String|array} the URL for login. If using array, the first element should be
- * the route to the login action, and the rest name-value pairs are GET parameters
- * to construct the login URL (e.g. array('/site/login')). If this property is null,
- * a 403 HTTP exception will be raised instead.
- * @see CController::createUrl
- */
- Yii.CWebUser.prototype.loginUrl = ['/site/login'];
- /**
- * @var {Array} the property values (in name-value pairs) used to initialize the identity cookie.
- * Any property of {@link CHttpCookie} may be initialized.
- * This property is effective only when {@link allowAutoLogin} is true.
- * @since 1.0.5
- */
- Yii.CWebUser.prototype.identityCookie = null;
- /**
- * @var {Integer} timeout in seconds after which user is logged out if inactive.
- * If this property is not set, the user will be logged out after the current session expires
- * (c.f. {@link CHttpSession::timeout}).
- * @since 1.1.7
- */
- Yii.CWebUser.prototype.authTimeout = null;
- /**
- * @var {Boolean} whether to automatically renew the identity cookie each time a page is requested.
- * Defaults to false. This property is effective only when {@link allowAutoLogin} is true.
- * When this is false, the identity cookie will expire after the specified duration since the user
- * is initially logged in. When this is true, the identity cookie will expire after the specified duration
- * since the user visits the site the last time.
- * @see allowAutoLogin
- * @since 1.1.0
- */
- Yii.CWebUser.prototype.autoRenewCookie = false;
- /**
- * @var {Boolean} whether to automatically update the validity of flash messages.
- * Defaults to true, meaning flash messages will be valid only in the current and the next requests.
- * If this is set false, you will be responsible for ensuring a flash message is deleted after usage.
- * (This can be achieved by calling {@link getFlash} with the 3rd parameter being true).
- * @since 1.1.7
- */
- Yii.CWebUser.prototype.autoUpdateFlash = true;
- Yii.CWebUser.prototype._keyPrefix = null;
- Yii.CWebUser.prototype._access = [];
- /**
- * PHP magic method.
- * This method is overriden so that persistent states can be accessed like properties.
- * @param {String} name property name
- * @returns {Mixed} property value
- * @since 1.0.3
- */
- Yii.CWebUser.prototype.get = function (name) {
- if(this.hasState(name)) {
- return this.getState(name);
- }
- else {
- return Yii.CApplicationComponent.prototype.get.call(this, name);
- }
- };
- /**
- * PHP magic method.
- * This method is overriden so that persistent states can be set like properties.
- * @param {String} name property name
- * @param {Mixed} value property value
- * @since 1.0.3
- */
- Yii.CWebUser.prototype.set = function (name, value) {
- if(this.hasState(name)) {
- this.setState(name,value);
- }
- else {
- Yii.CApplicationComponent.prototype.set.call(this, name,value);
- }
- };
- /**
- * PHP magic method.
- * This method is overriden so that persistent states can also be checked for null value.
- * @param {String} name property name
- * @since 1.0.3
- */
- Yii.CWebUser.prototype.isset = function (name) {
- if(this.hasState(name)) {
- return this.getState(name)!==null;
- }
- else {
- return Yii.CApplicationComponent.prototype.isset.call(this,name);
- }
- };
- /**
- * PHP magic method.
- * This method is overriden so that persistent states can also be unset.
- * @param {String} name property name
- * @throws {Yii.CException} if the property is read only.
- * @since 1.0.3
- */
- Yii.CWebUser.prototype.unset = function (name) {
- if(this.hasState(name)) {
- this.setState(name,null);
- }
- else {
- Yii.CApplicationComponent.prototype.unset.call(this, name);
- }
- };
- /**
- * Initializes the application component.
- * This method overrides the parent implementation by starting session,
- * performing cookie-based authentication if enabled, and updating the flash variables.
- */
- Yii.CWebUser.prototype.init = function () {
- Yii.CApplicationComponent.prototype.init();
-
- if(this.autoUpdateFlash) {
- this.updateFlash();
- }
- this.updateAuthStatus();
- };
- /**
- * Logs in a user.
- *
- * The user identity information will be saved in storage that is
- * persistent during the user session. By default, the storage is simply
- * the session storage. If the duration parameter is greater than 0,
- * a cookie will be sent to prepare for cookie-based login in future.
- *
- * Note, you have to set {@link allowAutoLogin} to true
- * if you want to allow user to be authenticated based on the cookie information.
- *
- * @param {IUserIdentity} identity the user identity (which should already be authenticated)
- * @param {Integer} duration number of seconds that the user can remain in logged-in status. Defaults to 0, meaning login till the user closes the browser.
- * If greater than 0, cookie-based login will be used. In this case, {@link allowAutoLogin}
- * must be set true, otherwise an exception will be thrown.
- */
- Yii.CWebUser.prototype.login = function (identity, duration) {
- var id, states;
- if (duration === undefined) {
- duration = 0;
- }
- id=identity.getId();
- states=identity.getPersistentStates();
- if(this.beforeLogin(id,states,false))
- {
- this.changeIdentity(id,identity.getName(),states);
- if(duration>0)
- {
- if(this.allowAutoLogin) {
- this.saveToCookie(duration);
- }
- else {
- throw new Yii.CException(Yii.t('yii','{class}.allowAutoLogin must be set true in order to use cookie-based authentication.',
- {'{class}':this.getClassName()}));
- }
- }
- this.afterLogin(false);
- }
- };
- /**
- * Logs out the current user.
- * This will remove authentication-related session data.
- * If the parameter is true, the whole session will be destroyed as well.
- * @param {Boolean} destroySession whether to destroy the whole session. Defaults to true. If false,
- * then {@link clearStates} will be called, which removes only the data stored via {@link setState}.
- * This parameter has been available since version 1.0.7. Before 1.0.7, the behavior
- * is to destroy the whole session.
- */
- Yii.CWebUser.prototype.logout = function (destroySession) {
- var cookie;
- if (destroySession === undefined) {
- destroySession = true;
- }
- if(this.beforeLogout()) {
- if(this.allowAutoLogin) {
- Yii.app().getRequest().getCookies().remove(this.getStateKeyPrefix());
- if(this.identityCookie!==null) {
- cookie=this.createIdentityCookie(this.getStateKeyPrefix());
- cookie.value=null;
- cookie.expire=0;
- Yii.app().getRequest().getCookies().add(cookie.name,cookie);
- }
- }
- if(destroySession) {
- Yii.app().getSession().destroy();
- }
- else {
- this.clearStates();
- }
- this.afterLogout();
- }
- };
- /**
- * @returns {Boolean} whether the current application user is a guest.
- */
- Yii.CWebUser.prototype.getIsGuest = function () {
- return this.getState('__id')===null;
- };
- /**
- * @returns {Mixed} the unique identifier for the user. If null, it means the user is a guest.
- */
- Yii.CWebUser.prototype.getId = function () {
- return this.getState('__id');
- };
- /**
- * @param {Mixed} value the unique identifier for the user. If null, it means the user is a guest.
- */
- Yii.CWebUser.prototype.setId = function (value) {
- this.setState('__id',value);
- };
- /**
- * Returns the unique identifier for the user (e.g. username).
- * This is the unique identifier that is mainly used for display purpose.
- * @returns {String} the user name. If the user is not logged in, this will be {@link guestName}.
- */
- Yii.CWebUser.prototype.getName = function () {
- var name;
- if((name=this.getState('__name'))!==null) {
- return name;
- }
- else {
- return this.guestName;
- }
- };
- /**
- * Sets the unique identifier for the user (e.g. username).
- * @param {String} value the user name.
- * @see getName
- */
- Yii.CWebUser.prototype.setName = function (value) {
- this.setState('__name',value);
- };
- /**
- * Returns the URL that the user should be redirected to after successful login.
- * This property is usually used by the login action. If the login is successful,
- * the action should read this property and use it to redirect the user browser.
- * @param {String} defaultUrl the default return URL in case it was not set previously. If this is null,
- * the application entry URL will be considered as the default return URL.
- * @returns {String} the URL that the user should be redirected to after login.
- * @see loginRequired
- */
- Yii.CWebUser.prototype.getReturnUrl = function (defaultUrl) {
- if (defaultUrl === undefined) {
- defaultUrl = null;
- }
- return this.getState('__returnUrl', defaultUrl===null ? Yii.app().getRequest().getScriptUrl() : Yii.CHtml.normalizeUrl(defaultUrl));
- };
- /**
- * @param {String} value the URL that the user should be redirected to after login.
- */
- Yii.CWebUser.prototype.setReturnUrl = function (value) {
- this.setState('__returnUrl',value);
- };
- /**
- * Redirects the user browser to the login page.
- * Before the redirection, the current URL (if it's not an AJAX url) will be
- * kept in {@link returnUrl} so that the user browser may be redirected back
- * to the current page after successful login. Make sure you set {@link loginUrl}
- * so that the user browser can be redirected to the specified login URL after
- * calling this method.
- * After calling this method, the current request processing will be terminated.
- */
- Yii.CWebUser.prototype.loginRequired = function () {
- var app, request, url, route;
- app=Yii.app();
- request=app.getRequest();
- if(!request.getIsAjaxRequest()) {
- this.setReturnUrl(request.getUrl());
- }
- if((url=this.loginUrl)!==null)
- {
- if(Object.prototype.toString.call(url) === '[object Array]')
- {
- route=url[0] !== undefined ? url[0] : app.defaultController;
- url=app.createUrl(route,php.array_splice(url,1));
- }
- request.redirect(url);
- }
- else {
- throw new Yii.CHttpException(403,Yii.t('yii','Login Required'));
- }
- };
- /**
- * This method is called before logging in a user.
- * You may override this method to provide additional security check.
- * For example, when the login is cookie-based, you may want to verify
- * that the user ID together with a random token in the states can be found
- * in the database. This will prevent hackers from faking arbitrary
- * identity cookies even if they crack down the server private key.
- * @param {Mixed} id the user ID. This is the same as returned by {@link getId()}.
- * @param {Array} states a set of name-value pairs that are provided by the user identity.
- * @param {Boolean} fromCookie whether the login is based on cookie
- * @returns {Boolean} whether the user should be logged in
- * @since 1.1.3
- */
- Yii.CWebUser.prototype.beforeLogin = function (id, states, fromCookie) {
- return true;
- };
- /**
- * This method is called after the user is successfully logged in.
- * You may override this method to do some postprocessing (e.g. log the user
- * login IP and time; load the user permission information).
- * @param {Boolean} fromCookie whether the login is based on cookie.
- * @since 1.1.3
- */
- Yii.CWebUser.prototype.afterLogin = function (fromCookie) {
- };
- /**
- * This method is invoked when calling {@link logout} to log out a user.
- * If this method return false, the logout action will be cancelled.
- * You may override this method to provide additional check before
- * logging out a user.
- * @returns {Boolean} whether to log out the user
- * @since 1.1.3
- */
- Yii.CWebUser.prototype.beforeLogout = function () {
- return true;
- };
- /**
- * This method is invoked right after a user is logged out.
- * You may override this method to do some extra cleanup work for the user.
- * @since 1.1.3
- */
- Yii.CWebUser.prototype.afterLogout = function () {
- };
- /**
- * Populates the current user object with the information obtained from cookie.
- * This method is used when automatic login ({@link allowAutoLogin}) is enabled.
- * The user identity information is recovered from cookie.
- * Sufficient security measures are used to prevent cookie data from being tampered.
- * @see saveToCookie
- */
- Yii.CWebUser.prototype.restoreFromCookie = function () {
- var app, cookie, data, id, name, duration, states;
- app=Yii.app();
- cookie=app.getRequest().getCookies().itemAt(this.getStateKeyPrefix());
- if(cookie && !php.empty(cookie.value) && (data=app.getSecurityManager().validateData(cookie.value))!==false) {
- data=Yii.CJSON.decode(data);
- if(Object.prototype.toString.call(data) === '[object Array]' && data[0] !== undefined) {
- id = data[0];
- name = data[1];
- duration = data[2];
- states = data[3];
- if(this.beforeLogin(id,states,true)) {
- this.changeIdentity(id,name,states);
- if(this.autoRenewCookie) {
- cookie.expire=php.time()+duration;
- app.getRequest().getCookies().add(cookie.name,cookie);
- }
- this.afterLogin(true);
- }
- }
- }
- };
- /**
- * Renews the identity cookie.
- * This method will set the expiration time of the identity cookie to be the current time
- * plus the originally specified cookie duration.
- * @since 1.1.3
- */
- Yii.CWebUser.prototype.renewCookie = function () {
- var cookies, cookie, data;
- cookies=Yii.app().getRequest().getCookies();
- cookie=cookies.itemAt(this.getStateKeyPrefix());
- if(cookie && !php.empty(cookie.value) && (data=Yii.app().getSecurityManager().validateData(cookie.value))!==false) {
- data=Yii.CJSON.decode(data);
- if(Object.prototype.toString.call(data) === '[object Array]' && data[0] !== undefined) {
- cookie.expire=php.time()+data[2];
- cookies.add(cookie.name,cookie);
- }
- }
- };
- /**
- * Saves necessary user data into a cookie.
- * This method is used when automatic login ({@link allowAutoLogin}) is enabled.
- * This method saves user ID, username, other identity states and a validation key to cookie.
- * These information are used to do authentication next time when user visits the application.
- * @param {Integer} duration number of seconds that the user can remain in logged-in status. Defaults to 0, meaning login till the user closes the browser.
- * @see restoreFromCookie
- */
- Yii.CWebUser.prototype.saveToCookie = function (duration) {
- var app, cookie, data;
- app=Yii.app();
- cookie=this.createIdentityCookie(this.getStateKeyPrefix());
- cookie.expire=php.time()+duration;
- data=[
- this.getId(),
- this.getName(),
- duration,
- this.saveIdentityStates()
- ];
- cookie.value=app.getSecurityManager().hashData(Yii.CJSON.encode(data));
- app.getRequest().getCookies().add(cookie.name,cookie);
- };
- /**
- * Creates a cookie to store identity information.
- * @param {String} cookieName the cookie name
- * @returns {Yii.CHttpCookie} the cookie used to store identity information
- * @since 1.0.5
- */
- Yii.CWebUser.prototype.createIdentityCookie = function (cookieName) {
- var name, cookie, value;
- cookie=new Yii.CHttpCookie(cookieName,'');
- if(Object.prototype.toString.call(this.identityCookie) === '[object Array]') {
- for (name in this.identityCookie) {
- if (this.identityCookie.hasOwnProperty(name)) {
- value = this.identityCookie[name];
- cookie.name=value;
- }
- }
- }
- return cookie;
- };
- /**
- * @returns {String} a prefix for the name of the session variables storing user session data.
- */
- Yii.CWebUser.prototype.getStateKeyPrefix = function () {
- if(this._keyPrefix!==null) {
- return this._keyPrefix;
- }
- else {
- return (this._keyPrefix=php.md5('Yii.'+php.get_class(this)+'.'+Yii.app().getId()));
- }
- };
- /**
- * @param {String} value a prefix for the name of the session variables storing user session data.
- * @since 1.0.9
- */
- Yii.CWebUser.prototype.setStateKeyPrefix = function (value) {
- this._keyPrefix=value;
- };
- /**
- * Returns the value of a variable that is stored in user session.
- *
- * This function is designed to be used by CWebUser descendant classes
- * who want to store additional user information in user session.
- * A variable, if stored in user session using {@link setState} can be
- * retrieved back using this function.
- *
- * @param {String} key variable name
- * @param {Mixed} defaultValue default value
- * @returns {Mixed} the value of the variable. If it doesn't exist in the session,
- * the provided default value will be returned
- * @see setState
- */
- Yii.CWebUser.prototype.getState = function (key, defaultValue) {
- // TODO: Fix this !
- var _SESSION = {};
- if (defaultValue === undefined) {
- defaultValue = null;
- }
- key=this.getStateKeyPrefix()+key;
- return _SESSION[key] !== undefined ? _SESSION[key] : defaultValue;
- };
- /**
- * Stores a variable in user session.
- *
- * This function is designed to be used by CWebUser descendant classes
- * who want to store additional user information in user session.
- * By storing a variable using this function, the variable may be retrieved
- * back later using {@link getState}. The variable will be persistent
- * across page requests during a user session.
- *
- * @param {String} key variable name
- * @param {Mixed} value variable value
- * @param {Mixed} defaultValue default value. If $value===$defaultValue, the variable will be
- * removed from the session
- * @see getState
- */
- Yii.CWebUser.prototype.setState = function (key, value, defaultValue) {
- // TODO: Fix this!
- var _SESSION = {};
- if (defaultValue === undefined) {
- defaultValue = null;
- }
- key=this.getStateKeyPrefix()+key;
- if(value===defaultValue) {
- delete _SESSION[key];
- }
- else {
- _SESSION[key]=value;
- }
- };
- /**
- * Returns a value indicating whether there is a state of the specified name.
- * @param {String} key state name
- * @returns {Boolean} whether there is a state of the specified name.
- * @since 1.0.3
- */
- Yii.CWebUser.prototype.hasState = function (key) {
- // TODO: Fix this!
- var _SESSION = {};
- key=this.getStateKeyPrefix()+key;
- return _SESSION[key] !== undefined;
- };
- /**
- * Clears all user identity information from persistent storage.
- * This will remove the data stored via {@link setState}.
- */
- Yii.CWebUser.prototype.clearStates = function () {
- // TODO: Fix this!
- var keys, _SESSION = {}, prefix, n, i, key;
- keys=php.array_keys(_SESSION);
- prefix=this.getStateKeyPrefix();
- n=php.strlen(prefix);
- for (i in keys) {
- if (keys.hasOwnProperty(i)) {
- key = keys[i];
- if(!php.strncmp(key,prefix,n)) {
- delete _SESSION[key];
- }
- }
- }
- };
- /**
- * Returns all flash messages.
- * This method is similar to {@link getFlash} except that it returns all
- * currently available flash messages.
- * @param {Boolean} deleteVar whether to delete the flash messages after calling this method.
- * @returns {Array} flash messages (key => message).
- * @since 1.1.3
- */
- Yii.CWebUser.prototype.getFlashes = function (deleteVar) {
- var flashes, prefix, keys, _SESSION = {}, n, i, key;
- if (deleteVar === undefined) {
- deleteVar = true;
- }
- flashes=[];
- prefix=this.getStateKeyPrefix()+this.FLASH_KEY_PREFIX;
- keys=php.array_keys(_SESSION);
- n=php.strlen(prefix);
- for (i in keys)
- {
- if (keys.hasOwnProperty(i)) {
- key = keys[i];
- if(!php.strncmp(key,prefix,n))
- {
- flashes[key.slice(n)]=_SESSION[key];
- if(deleteVar) {
- delete _SESSION[key];
- }
- }
- }
- }
- if(deleteVar) {
- this.setState(this.FLASH_COUNTERS,[]);
- }
- return flashes;
- };
- /**
- * Returns a flash message.
- * A flash message is available only in the current and the next requests.
- * @param {String} key key identifying the flash message
- * @param {Mixed} defaultValue value to be returned if the flash message is not available.
- * @param {Boolean} deleteVar whether to delete this flash message after accessing it.
- * Defaults to true. This parameter has been available since version 1.0.2.
- * @returns {Mixed} the message message
- */
- Yii.CWebUser.prototype.getFlash = function (key, defaultValue, deleteVar) {
- var value;
- if (defaultValue === undefined) {
- defaultValue = null;
- }
- if (deleteVar === undefined) {
- deleteVar = true;
- }
- value=this.getState(this.FLASH_KEY_PREFIX+key,defaultValue);
- if(deleteVar) {
- this.setFlash(key,null);
- }
- return value;
- };
- /**
- * Stores a flash message.
- * A flash message is available only in the current and the next requests.
- * @param {String} key key identifying the flash message
- * @param {Mixed} value flash message
- * @param {Mixed} defaultValue if this value is the same as the flash message, the flash message
- * will be removed. (Therefore, you can use setFlash('key',null) to remove a flash message.)
- */
- Yii.CWebUser.prototype.setFlash = function (key, value, defaultValue) {
- var counters;
- if (defaultValue === undefined) {
- defaultValue = null;
- }
- this.setState(this.FLASH_KEY_PREFIX+key,value,defaultValue);
- counters=this.getState(this.FLASH_COUNTERS,[]);
- if(value===defaultValue) {
- delete counters[key];
- }
- else {
- counters[key]=0;
- }
- this.setState(this.FLASH_COUNTERS,counters,[]);
- };
- /**
- * @param {String} key key identifying the flash message
- * @returns {Boolean} whether the specified flash message exists
- */
- Yii.CWebUser.prototype.hasFlash = function (key) {
- return this.getFlash(key, null, false)!==null;
- };
- /**
- * Changes the current user with the specified identity information.
- * This method is called by {@link login} and {@link restoreFromCookie}
- * when the current user needs to be populated with the corresponding
- * identity information. Derived classes may override this method
- * by retrieving additional user-related information. Make sure the
- * parent implementation is called first.
- * @param {Mixed} id a unique identifier for the user
- * @param {String} name the display name for the user
- * @param {Array} states identity states
- */
- Yii.CWebUser.prototype.changeIdentity = function (id, name, states) {
- Yii.app().getSession().regenerateID();
- this.setId(id);
- this.setName(name);
- this.loadIdentityStates(states);
- };
- /**
- * Retrieves identity states from persistent storage and saves them as an array.
- * @returns {Array} the identity states
- */
- Yii.CWebUser.prototype.saveIdentityStates = function () {
- var states, nameDummy, name, dummy;
- states=[];
- nameDummy = this.getState(this.STATES_VAR,[]);
- for (name in nameDummy) {
- if (nameDummy.hasOwnProperty(name)) {
- dummy = nameDummy[name];
- states[name]=this.getState(name);
- }
- }
- return states;
- };
- /**
- * Loads identity states from an array and saves them to persistent storage.
- * @param {Array} states the identity states
- */
- Yii.CWebUser.prototype.loadIdentityStates = function (states) {
- var names, name, value;
- names=[];
- if(Object.prototype.toString.call(states) === '[object Array]') {
- for (name in states) {
- if (states.hasOwnProperty(name)) {
- value = states[name];
- this.setState(name,value);
- names[name]=true;
- }
- }
- }
- this.setState(this.STATES_VAR,names);
- };
- /**
- * Updates the internal counters for flash messages.
- * This method is internally used by {@link CWebApplication}
- * to maintain the availability of flash messages.
- */
- Yii.CWebUser.prototype.updateFlash = function () {
- var counters, count, key;
- counters=this.getState(this.FLASH_COUNTERS);
- if(Object.prototype.toString.call(counters) !== '[object Array]') {
- return;
- }
- for (key in counters) {
- if (counters.hasOwnProperty(key)) {
- count = counters[key];
- if(count)
- {
- delete counters[key];
- this.setState(this.FLASH_KEY_PREFIX+key,null);
- }
- else {
- counters[key]++;
- }
- }
- }
- this.setState(this.FLASH_COUNTERS,counters,[]);
- };
- /**
- * Updates the authentication status according to {@link authTimeout}.
- * If the user has been inactive for {@link authTimeout} seconds,
- * he will be automatically logged out.
- * @since 1.1.7
- */
- Yii.CWebUser.prototype.updateAuthStatus = function () {
- var expires;
- if(this.authTimeout!==null && !this.getIsGuest()) {
- expires=this.getState(this.AUTH_TIMEOUT_VAR);
- if (expires!==null && expires < php.time()) {
- this.logout(false);
- }
- else {
- this.setState(this.AUTH_TIMEOUT_VAR,php.time()+this.authTimeout);
- }
- }
- };
- /**
- * Performs access check for this user.
- * @param {String} operation the name of the operation that need access check.
- * @param {Array} params name-value pairs that would be passed to business rules associated
- * with the tasks and roles assigned to the user.
- * @param {Boolean} allowCaching whether to allow caching the result of access check.
- * This parameter has been available since version 1.0.5. When this parameter
- * is true (default), if the access check of an operation was performed before,
- * its result will be directly returned when calling this method to check the same operation.
- * If this parameter is false, this method will always call {@link CAuthManager::checkAccess}
- * to obtain the up-to-date access result. Note that this caching is effective
- * only within the same request.
- * @returns {Boolean} whether the operations can be performed by this user.
- */
- Yii.CWebUser.prototype.checkAccess = function (operation, params, allowCaching) {
- if (params === undefined) {
- params = [];
- }
- if (allowCaching === undefined) {
- allowCaching = true;
- }
- if(allowCaching && params===[] && this._access[operation] !== undefined) {
- return this._access[operation];
- }
- else {
- return (this._access[operation]=Yii.app().getAuthManager().checkAccess(operation,this.getId(),params));
- }
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CFilterChain represents a list of filters being applied to an action.
- *
- * CFilterChain executes the filter list by {@link run()}.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CFilterChain.php 3001 2011-02-24 16:42:44Z alexander.makarow $
- * @package system.web.filters
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CList
- */
- Yii.CFilterChain = function CFilterChain (data, readOnly) {
- if (data !== false) {
- this.construct(data, readOnly);
- }
- };
- Yii.CFilterChain.prototype = new Yii.CList(false);
- Yii.CFilterChain.prototype.constructor = Yii.CFilterChain;
- /**
- * @var {Yii.CController} the controller who executes the action.
- */
- Yii.CFilterChain.prototype.controller = null;
- /**
- * @var {Yii.CAction} the action being filtered by this chain.
- */
- Yii.CFilterChain.prototype.action = null;
- /**
- * @var {Integer} the index of the filter that is to be executed when calling {@link run()}.
- */
- Yii.CFilterChain.prototype.filterIndex = 0;
- /**
- * Constructor.
- * @param {Yii.CController} controller the controller who executes the action.
- * @param {Yii.CAction} action the action being filtered by this chain.
- */
- Yii.CFilterChain.prototype.construct = function (controller, action) {
- this.controller=controller;
- this.action=action;
- };
- /**
- * CFilterChain factory method.
- * This method creates a CFilterChain instance.
- * @param {Yii.CController} controller the controller who executes the action.
- * @param {Yii.CAction} action the action being filtered by this chain.
- * @param {Array} filters list of filters to be applied to the action.
- */
- Yii.CFilterChain.prototype.create = function (controller, action, filters) {
- var chain, actionID, i, filter, pos, matched, filterClass;
- chain=new Yii.CFilterChain(controller,action);
- actionID=action.getId();
- for (i in filters) {
- if (filters.hasOwnProperty(i)) {
- filter = filters[i];
- if(typeof(filter) === 'string') {
- // filterName [+|- action1 action2]
- if((pos=php.strpos(filter,'+'))!==false || (pos=php.strpos(filter,'-'))!==false) {
- matched=/\b{actionID}\b/i.exec(filter.slice(pos+1))>0;
- if((filter[pos]==='+')===matched) {
- filter=Yii.CInlineFilter.create(controller,php.trim(filter.slice(0, pos)));
- }
- }
- else {
- filter=Yii.CInlineFilter.create(controller,filter);
- }
- }
- }
- else if(typeof(filter) === "object") {
- // array('path.to.class [+|- action1, action2]','param1'=>'value1',...)
- if(filter[0] === undefined) {
- throw new Yii.CException(Yii.t('yii','The first element in a filter configuration must be the filter class.'));
- }
- filterClass=filter[0];
- delete filter[0];
- if((pos=php.strpos(filterClass,'+'))!==false || (pos=php.strpos(filterClass,'-'))!==false) {
- matched=((new RegExp("\\b" + actionID + "\\b","i")).exec(filterClass.slice(pos+1))>0);
- if((filterClass[pos]==='+')===matched) {
- filterClass=php.trim(filterClass.slice(0, pos));
- }
- else {
- continue;
- }
- }
- filter['class']=filterClass;
- filter=Yii.createComponent(filter);
- }
- if (typeof filter === "object") {
- filter.init();
- chain.add(filter);
- }
- }
- return chain;
- };
- /**
- * Inserts an item at the specified position.
- * This method overrides the parent implementation by adding
- * additional check for the item to be added. In particular,
- * only objects implementing {@link IFilter} can be added to the list.
- * @param {Integer} index the specified position.
- * @param {Mixed} item new item
- * @throws {Yii.CException} If the index specified exceeds the bound or the list is read-only, or the item is not an {@link IFilter} instance.
- */
- Yii.CFilterChain.prototype.insertAt = function (index, item) {
- if(item instanceof Yii.CFilter) {
- Yii.CList.prototype.insertAt.call(this,index,item);
- }
- else {
- throw new Yii.CException(Yii.t('yii','CFilterChain can only take objects implementing the IFilter interface.'));
- }
- };
- /**
- * Executes the filter indexed at {@link filterIndex}.
- * After this method is called, {@link filterIndex} will be automatically incremented by one.
- * This method is usually invoked in filters so that the filtering process
- * can continue and the action can be executed.
- */
- Yii.CFilterChain.prototype.run = function () {
- var filter;
- if(this.offsetExists(this.filterIndex)) {
- filter=this.itemAt(this.filterIndex++);
- Yii.trace('Running filter '+(filter instanceof Yii.CInlineFilter ? this.controller.getClassName()+'.filter'+filter.name+'()':filter.getClassName()+'.filter()'),'system.web.filters.CFilterChain');
- filter.filter(this);
- }
- else {
- this.controller.runAction(this.action);
- }
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CInlineFilter represents a filter defined as a controller method.
- *
- * CInlineFilter executes the 'filterXYZ($action)' method defined
- * in the controller, where the name 'XYZ' can be retrieved from the {@link name} property.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CInlineFilter.php 3026 2011-03-06 10:41:56Z haertl.mike $
- * @package system.web.filters
- * @since 1.0
- * @author Charles Pick
- * @class
- * @extends Yii.CFilter
- */
- Yii.CInlineFilter = function CInlineFilter () {
- };
- Yii.CInlineFilter.prototype = new Yii.CFilter();
- Yii.CInlineFilter.prototype.constructor = Yii.CInlineFilter;
- /**
- * @var {String} name of the filter. It stands for 'XYZ' in the filter method name 'filterXYZ'.
- */
- Yii.CInlineFilter.prototype.name = null;
- /**
- * Creates an inline filter instance.
- * The creation is based on a string describing the inline method name
- * and action names that the filter shall or shall not apply to.
- * @param {Yii.CController} controller the controller who hosts the filter methods
- * @param {String} filterName the filter name
- * @returns {Yii.CInlineFilter} the created instance
- * @throws {Yii.CException} if the filter method does not exist
- */
- Yii.CInlineFilter.prototype.create = function (controller, filterName) {
- var filter;
- if(controller['filter'+php.ucfirst(filterName)] !== undefined) {
- filter=new Yii.CInlineFilter();
- filter.name=filterName;
- return filter;
- }
- else {
- throw new Yii.CException(Yii.t('yii','Filter "{filter}" is invalid. Controller "{class}" does not have the filter method "filter{filter}".',
- {'{filter}':filterName, '{class}':controller.getClassName()}));
- }
- };
- /**
- * Performs the filtering.
- * This method calls the filter method defined in the controller class.
- * @param {Yii.CFilterChain} filterChain the filter chain that the filter is on.
- */
- Yii.CInlineFilter.prototype.filter = function (filterChain) {
- var method;
- method='filter'+php.ucfirst(this.name);
- filterChain.controller[method](filterChain);
- };/*global Yii, php, $, jQuery, alert, clearInterval, clearTimeout, document, event, frames, history, Image, location, name, navigator, Option, parent, screen, setInterval, setTimeout, window, XMLHttpRequest */
- /**
- * CForm represents a form object that contains form input specifications.
- *
- * The main purpose of introducing the abstraction of form objects is to enhance the
- * reusability of forms. In particular, we can divide a form in two parts: those
- * that specify each individual form inputs, and those that decorate the form inputs.
- * A CForm object represents the former part. It relies on the rendering process to
- * accomplish form input decoration. Reusability is mainly achieved in the rendering process.
- * That is, a rendering process can be reused to render different CForm objects.
- *
- * A form can be rendered in different ways. One can call the {@link render} method
- * to get a quick form rendering without writing any HTML code; one can also override
- * {@link render} to render the form in a different layout; and one can use an external
- * view template to render each form element explicitly. In these ways, the {@link render}
- * method can be applied to all kinds of forms and thus achieves maximum reusability;
- * while the external view template keeps maximum flexibility in rendering complex forms.
- *
- * Form input specifications are organized in terms of a form element hierarchy.
- * At the root of the hierarchy, it is the root CForm object. The root form object maintains
- * its children in two collections: {@link elements} and {@link buttons}.
- * The former contains non-button form elements ({@link CFormStringElement},
- * {@link CFormInputElement} and CForm); while the latter mainly contains
- * button elements ({@link CFormButtonElement}). When a CForm object is embedded in the
- * {@link elements} collection, it is called a sub-form which can have its own {@link elements}
- * and {@link buttons} collections and thus form the whole form hierarchy.
- *
- * Sub-forms are mainly used to handle multiple models. For example, in a user
- * registration form, we can have the root form to collect input for the user
- * table while a sub-form to collect input for the profile table. Sub-form is also
- * a good way to partition a lengthy form into shorter ones, even though all inputs
- * may belong to the same model.
- *
- * Form input specifications are given in terms of a configuration array which is
- * used to initialize the property values of a CForm object. The {@link elements} and
- * {@link buttons} properties need special attention as they are the main properties
- * to be configured. To configure {@link elements}, we should give it an array like
- * the following:
- * <pre>
- * 'elements':{
- * 'username':{'type':'text', 'maxlength':80},
- * 'password':{'type':'password', 'maxlength':80},
- * }
- * </pre>
- * The above code specifies two input elements: 'username' and 'password'. Note the model
- * object must have exactly the same attributes 'username' and 'password'. Each element
- * has a type which specifies what kind of input should be used. The rest of the array elements
- * (e.g. 'maxlength') in an input specification are rendered as HTML element attributes
- * when the input field is rendered. The {@link buttons} property is configured similarly.
- *
- * For more details about configuring form elements, please refer to {@link CFormInputElement}
- * and {@link CFormButtonElement}.
- *
- * @originalAuthor Qiang Xue <qiang.xue@gmail.com>
- * @version $Id: CForm.php 3076 2011-03-14 13:16:43Z qiang.xue $
- * @package system.web.form
- * @since 1.1
- * @author Charles Pick
- * @class
- * @extends Yii.CFormElement
- */
- Yii.CForm = function CForm (config, model, parent) {
- if (config !== false) {
- this.construct(config, model, parent);
- }
- };
- Yii.CForm.prototype = new Yii.CFormElement(false);
- Yii.CForm.prototype.constructor = Yii.CForm;
- /**
- * @var {String} the title for this form. By default, if this is set, a fieldset may be rendered
- * around the form body using the title as its legend. Defaults to null.
- */
- Yii.CForm.prototype.title = null;
- /**
- * @var {String} the description of this form.
- */
- Yii.CForm.prototype.description = null;
- /**
- * @var {String} the submission method of this form. Defaults to 'post'.
- * This property is ignored when this form is a sub-form.
- */
- Yii.CForm.prototype.method = 'post';
- /**
- * @var {Mixed} the form action URL (see {@link CHtml::normalizeUrl} for details about this parameter.)
- * Defaults to an empty string, meaning the current request URL.
- * This property is ignored when this form is a sub-form.
- */
- Yii.CForm.prototype.action = '';
- /**
- * @var {String} the name of the class for representing a form input element. Defaults to 'CFormInputElement'.
- */
- Yii.CForm.prototype.inputElementClass = 'CFormInputElement';
- /**
- * @var {String} the name of the class for representing a form button element. Defaults to 'CFormButtonElement'.
- */
- Yii.CForm.prototype.buttonElementClass = 'CFormButtonElement';
- /**
- * @var {Array} HTML attribute values for the form tag. When the form is embedded within another form,
- * this property will be used to render the HTML attribute values for the fieldset enclosing the child form.
- */
- Yii.CForm.prototype.attributes = {};
- /**
- * @var {Boolean} whether to show error summary. Defaults to false.
- */
- Yii.CForm.prototype.showErrorSummary = false;
- /**
- * @var {Array} the configuration used to create the active form widget.
- * The widget will be used to render the form tag and the error messages.
- * The 'class' option is required, which specifies the class of the widget.
- * The rest of the options will be passed to {@link CBaseController::beginWidget()} call.
- * Defaults to array('class'=>'CActiveForm').
- * @since 1.1.1
- */
- Yii.CForm.prototype.activeForm = {'class':'CActiveForm'};
- Yii.CForm.prototype._model = null;
- Yii.CForm.prototype._elements = null;
- Yii.CForm.prototype._buttons = null;
- Yii.CForm.prototype._activeForm = null;
- /**
- * Constructor.
- * If you override this method, make sure you do not modify the method
- * signature, and also make sure you call the parent implementation.
- * @param {Mixed} config the configuration for this form. It can be a configuration array
- * or the path alias of a PHP script file that returns a configuration array.
- * The configuration array consists of name-value pairs that are used to initialize
- * the properties of this form.
- * @param {Yii.CModel} model the model object associated with this form. If it is null,
- * the parent's model will be used instead.
- * @param {Mixed} parent the direct parent of this form. This could be either a {@link CBaseController}
- * object (a controller or a widget), or a {@link CForm} object.
- * If the former, it means the form is a top-level form; if the latter, it means this form is a sub-form.
- */
- Yii.CForm.prototype.construct = function (config, model, parent) {
- if (model === undefined) {
- model = null;
- }
- if (parent === undefined) {
- parent = null;
- }
- this.setModel(model);
- if(parent===null) {
- parent=Yii.app().getController();
- }
- Yii.CFormElement.prototype.construct.call(this,config,parent);
- this.init();
- };
- /**
- * Initializes this form.
- * This method is invoked at the end of the constructor.
- * You may override this method to provide customized initialization (such as
- * configuring the form object).
- */
- Yii.CForm.prototype.init = function () {
- };
- /**
- * Returns a value indicating whether this form is submitted.
- * @param {String} buttonName the name of the submit button
- * @param {Boolean} loadData whether to call {@link loadData} if the form is submitted so that
- * the submitted data can be populated to the associated models.
- * @returns {Boolean} whether this form is submitted.
- * @see loadData
- */
- Yii.CForm.prototype.submitted = function (buttonName, loadData) {
- var ret;
- if (buttonName === undefined) {
- buttonName = 'submit';
- }
- if (loadData === undefined) {
- loadData = true;
- }
- ret=this.clicked(this.getUniqueId()) && this.clicked(buttonName);
- if(ret && loadData) {
- this.loadData();
- }
- return ret;
- };
- /**
- * Returns a value indicating whether the specified button is clicked.
- * @param {String} name the button name
- * @returns {Boolean} whether the button is clicked.
- */
- Yii.CForm.prototype.clicked = function (name) {
- return Yii.app().getRequest().getParam(name) !== undefined;
-
- };
- /**
- * Validates the models associated with this form.
- * All models, including those associated with sub-forms, will perform
- * the validation. You may use {@link CModel::getErrors()} to retrieve the validation
- * error messages.
- * @returns {Boolean} whether all models are valid
- */
- Yii.CForm.prototype.validate = function () {
- var ret, i, modelList, model;
- ret=true;
- modelList = this.getModels();
- for (i in modelList) {
- if (modelList.hasOwnProperty(i)) {
- model = modelList[i];
- ret=model.validate() && ret;
- }
- }
- return ret;
- };
- /**
- * Loads the submitted data into the associated model(s) to the form.
- * This method will go through all models associated with this form and its sub-forms
- * and massively assign the submitted data to the models.
- * @see submitted
- */
- Yii.CForm.prototype.loadData = function () {
- var classVar;
- if(this._model!==null) {
- classVar=this._model.getClassName();
- if(Yii.app().getRequest().params[classVar] !== undefined) {
- this._model.setAttributes(Yii.app().getRequest().params[classVar]);
- }
- }
- this.getElements().forEach(function(i, element) {
- if(element instanceof Yii.CForm) {
- element.loadData();
- }
- });
-
- };
- /**
- * @returns {Yii.CForm} the top-level form object
- */
- Yii.CForm.prototype.getRoot = function () {
- var root;
- root=this;
- while(root.getParent() instanceof Yii.CForm) {
- root=root.getParent();
- }
- return root;
- };
- /**
- * @returns {Yii.CActiveForm} the active form widget associated with this form.
- * This method will return the active form widget as specified by {@link activeForm}.
- * @since 1.1.1
- */
- Yii.CForm.prototype.getActiveFormWidget = function () {
- if(this._activeForm!==null) {
- return this._activeForm;
- }
- else {
- return this.getRoot()._activeForm;
- }
- };
- /**
- * @returns {Yii.CBaseController} the owner of this form. This refers to either a controller or a widget
- * by which the form is created and rendered.
- */
- Yii.CForm.prototype.getOwner = function () {
- var owner;
- owner=this.getParent();
- while(owner instanceof Yii.CForm) {
- owner=owner.getParent();
- }
- return owner;
- };
- /**
- * Returns the model that this form is associated with.
- * @param {Boolean} checkParent whether to return parent's model if this form doesn't have model by itself.
- * @returns {Yii.CModel} the model associated with this form. If this form does not have a model,
- * it will look for a model in its ancestors.
- */
- Yii.CForm.prototype.getModel = function (checkParent) {
- var form;
- if (checkParent === undefined) {
- checkParent = true;
- }
- if(!checkParent) {
- return this._model;
- }
- form=this;
- while(form._model===null && form.getParent() instanceof Yii.CForm) {
- form=form.getParent();
- }
- return form._model;
- };
- /**
- * @param {Yii.CModel} model the model to be associated with this form
- */
- Yii.CForm.prototype.setModel = function (model) {
- this._model=model;
- };
- /**
- * Returns all models that are associated with this form or its sub-forms.
- * @returns {Array} the models that are associated with this form or its sub-forms.
- */
- Yii.CForm.prototype.getModels = function () {
- var models, i, elementList, element;
- models=[];
- if(this._model!==null) {
- models.push(this._model);
- }
- this.getElements().forEach(function(i, element) {
- if(element instanceof Yii.CForm) {
- models=php.array_merge(models,element.getModels());
- }
- });
-
- return models;
- };
- /**
- * Returns the input elements of this form.
- * This includes text strings, input elements and sub-forms.
- * Note that the returned result is a {@link CFormElementCollection} object, which
- * means you can use it like an array. For more details, see {@link CMap}.
- * @returns {Yii.CFormElementCollection} the form elements.
- */
- Yii.CForm.prototype.getElements = function () {
- if(this._elements===null) {
- this._elements=new Yii.CFormElementCollection(this,false);
- }
- return this._elements;
- };
- /**
- * Configures the input elements of this form.
- * The configuration must be an array of input configuration array indexed by input name.
- * Each input configuration array consists of name-value pairs that are used to initialize
- * a {@link CFormStringElement} object (when 'type' is 'string'), a {@link CFormElement} object
- * (when 'type' is a string ending with 'Form'), or a {@link CFormInputElement} object in
- * all other cases.
- * @param {Array} elements the button configurations
- */
- Yii.CForm.prototype.setElements = function (elements) {
- var collection, name, config;
- collection=this.getElements();
-
- Yii.forEach(elements,function (name, config) {
-
- collection.add(name,config);
- });
-
- };
- /**
- * Returns the button elements of this form.
- * Note that the returned result is a {@link CFormElementCollection} object, which
- * means you can use it like an array. For more details, see {@link CMap}.
- * @returns {Yii.CFormElementCollection} the form elements.
- */
- Yii.CForm.prototype.getButtons = function () {
- if(this._buttons===null) {
- this._buttons=new Yii.CFormElementCollection(this,true);
- }
- return this._buttons;
- };
- /**
- * Configures the buttons of this form.
- * The configuration must be an array of button configuration array indexed by button name.
- * Each button configuration array consists of name-value pairs that are used to initialize
- * a {@link CFormButtonElement} object.
- * @param {Array} buttons the button configurations
- */
- Yii.CForm.prototype